Eighteeen / CleanCode_Book_Study

📚 클린코드 북 스터디 📚
4 stars 0 forks source link

[Switch 문] - 추상팩토리에서 파생 클래스, 다형성 등을 사용하면 해결? #3

Closed sookyeonghwang closed 3 years ago

sookyeonghwang commented 3 years ago

예제 3-5 는 3-4의 코드를 해결한 코드라고 말하고 있습니다. 3-4에서 문제는 함수가 길고, '한가지' 작업만 수행하지 않고, SRP, OCP를 위반하는 문제들이 있다고 합니다.

하지만 3-5를 보면 함수가 짧아진건지, '한가지' 작업만 수행하는지 등을 이해하기가 힘듭니다. 추상 팩토리에 숨기고 다형성을 사용하면 해결되는 것인지,, 잘 모르겠습니다.

deepredk commented 3 years ago

링크의 코드엔 책에서 생략한 코드를 풀어서 써놨습니다.

3-4 코드 방식으로는 Employee에 대한 새 메서드를 하나 만들 때마다 switch문을 포함한 메서드가 하나 만들어져야 합니다 하지만 3-5 코드 방식으로는 switch문이 추상 팩토리 메서드에서 딱 한번만 사용됩니다.

switch문은 기본적으로 N가지 일을 할 수 밖에 없습니다. 그리고 불가피하게 써야만 할 때가 있습니다. 그럴 땐 쓰긴 쓰되 반복은 하지말자고 저자는 말하고 있습니다.

3-4 코드에서는 N가지 일을 하는 메서드가 반복됩니다. 3-5 코드에서는 N가지 일을 하는 메서드가 영원히 하나뿐입니다.

그러므로 3-5 코드가 더 좋은 게 맞습니다.

함수가 짧아졌는가 => 짧아졌다기보다 없어졌습니다. switch문을 포함한 함수가 여러개였는데 하나로 줄었으니까요 한가지 작업만 수행하는가 => switch문은 N가지 작업을 수행할 수 밖에 없습니다. 그래서 반복하지 않는게 최선입니다. 3-5 코드는 반복하지 않습니다

WinningBean commented 3 years ago

@deepredk 가 자세히 설명해 주신 것 같습니다.

특히 switch문을 포함한 함수가 여러개 였는데 하나로 줄었으니까요 라는 문장으로 이해가 더 빠르게 됐으리라 짐작합니다.

다른 방향으로 설명드리자면, 3-4 코드에서 calculatePay를 행하기 위해서는 Employee의 급여 계산에 대한 새 메서드를 하나 만들 때마다 switch문에 포함한 메서드가 하나 만들어져야 합니다.

3-5 코드에서는 Employee 추상 클래스를 상속받은 각 종류의 Employee의 급여계산은 해당 클래스 내에서 해결하고 있습니다. (책 p. 48 다형성으로 인해 실제 파생 클래스의 함수가 실행된다.) 파생 클래스가 더 생긴다면 3-5 코드의 makeEmployee는 수정될 수 밖에 없습니다. 이것은 switch문의 한계입니다. 하지만 저자의 의견 자체가 다형적 객체를 생성하는 코드 안에서는 switch문을 단 한 번 참아준다. 라는 것이죠.

그리고 3-4에서 switch문을 수정하는 것은 여러 일을 해결하기 위해서 이지만, 3-5에서 switch문을 수정하는 것은 오로지 파생 클래스를 구별하여 객체를 생성하는 한 가지 일만을 위해서 입니다. 여기에서 차이가 극명히 갈린다고 생각합니다.

3-5 코드를 사용하는 예제를 보면 더욱 이해가 빠를 것 같습니다. (일부 생략 및 간단하게 표현했습니다.)

class Main {
  public static void main(String[] args) {
    EmployeeRecord r;
    EmployeeFactory employeeFactory = new EmployeeFactoryImpl();
    Employee employee = employeeFactory.makeEmployee(r);

    Date today;
    Money pay = employee.calculatePay();
    if (employee.isPayday(today)) employee.deliverPay(pay);
  }
}

위에서 calculatePay() 가 어떻게 계산되고 있는지는 이미 employee가 makeEmployee를 통해 객체가 생성되었을 때 결정됩니다. 뒤의 계산에 대해서는 파생 클래스에서만 신경쓰면 되는 것이죠. 새로운 유형이 생겼다면 다른 곳에서는 신경쓰지 않고, makeEmployee만 수정됩니다. makeEmployee는 객체를 구별하여 다형적 객체를 생성해주는 한 가지 일만 하고, calculatePay, isPayday, deliverPay는 이제 구별따위 필요없습니다. 함수 이름에 맞는 오로지 한 가지 일만 합니다.

이제 다른 의미 있는 이름을 다른 함수를 추출할 틈이 없어보이죠.

함수 자체보다는 구조적으로 좀 더 크게 보면 이해가 쉬울 것 같습니다.

WinningBean commented 3 years ago

결론

목록 3-5는 switch문의 모든 문제점을 해결하지는 않지만, 목록 3-4의 SRP, OCP를 위반하는 문제는 해결한 코드이다.