추상화를 통한 깔끔한 코드 작성하기
clean code
  • JavaScript

추상화로 더 간결한 코드 작성하기

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의 유형이 생기더라도 수정해야 할 부분이 더 적어진다.