추상화로 더 간결한 코드 작성하기
const calculatePay = (employee) => {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}이와 같은 코드가 있다고 가정해보자. 직원의 유형에 따라 값을 계산해서 반환하는 함수이다.
이 함수에는 몇가지 문제가 있다.
- 함수가 길다.
- 함수가
한 가지일만 수행하고있지 않다. - SRP(Single Responsibility Principle)를 위반한다 => 코드를 변경할 이유가 여럿 존재한다
- OCP(Open Closed Principle)를 위반한다 => 새 직원 유형이 추가될 때 마다 코드를 변경해야 한다
살펴보면 새로운 employee의 유형이 추가될 때 마다 calculatePay함수가 수정되어야 한다 (switch에 case를 추가)
그리고 calculate**Pay 와 같은 추가적인 함수가 필요하게 된다.
이러한 코드는 아주 유해하다.
이 문제를 어떻게 해결하면 좋을까?
class Employee {
calculatePay() { throw new Error('this function must be implement'); };
}우선 class를 추가해준다. javaScript에서는 abstract를 지원하지 않기 때문에 이렇게 만들었다.
(javaScript에서 abstract class를 만들기위해 나는 이렇게 사용한다.)
그리고 interface도 만들어주자
class EmployeeFactory {
makeEmployee (e) {
switch (e.type) {
case COMMISSIONED:
return new CommissionedEmployee(e);
case HOURLY:
return new HourlyEmployee(e);
case SALARIED:
return new SalariedEmployee(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
}마지막으로 사용하는곳에서는..
const calculatePay = (e) => {
const employee = new EmployeeFactory.makeEmployee(e);
return employee.calculatePay();
}switch를 추상화하여 숨김으로써 함수의 길이가 짧아지고, 새로운 employee의 유형이 생기더라도 수정해야 할 부분이 더 적어진다.