관리 메뉴

너와 나의 스토리

[리팩터링] 11.8 생성자를 팩터리 함수로 바꾸기 Replace Constructor with Factory Function 본문

개발/Refactoring

[리팩터링] 11.8 생성자를 팩터리 함수로 바꾸기 Replace Constructor with Factory Function

노는게제일좋아! 2022. 1. 25. 13:40
반응형

배경

  • 생성자에는 일반 함수에는 없는 제약이 따라붙기도 한다.
  • 가령 자바 생성자는 반드시 그 생성자를 정의한 클래스의 인스턴스를 반환해야 한다.
    • 서브클래스의 인스턴스나 프락시를 반환할 수는 없다.
  • 기본 이름(생성자 이름)보다 적절한 이름이 있어도 사용할 수가 없다.
  • 생성자를 호출하려면 특별한 연산자(보통 new)를 사용해야 해서 일반 함수가 오길 기대하는 자리에는 쓰기 어렵다.
  • 팩토리 함수에는 이런 제약이 없다.
Before After
leadEngineer = new Employee(document.leadEngineer, 'E'); leadEngineer = createEngineer(document.leadEngineer);

 

절차

  1. 팩터리팩토리 함수를 만든다. 팩토리 함수의 본문에서는 원래의 생성자를 호출한다.
  2. 생성자를 호출하던 코드를 팩터리 함수 호출로 바꾼다.
  3. 하나씩 수정할 때마다 테스트한다.
  4. 생성자의 가시 범위가 최소가 되도록 제한한다.

 

예시

  • 직원(Employee) 클래스
    • class Employee {
          constructor(name, typeCode){
              this._name = name;
              this._typeCode = typeCode;
          }
          get name() {return this._naame;}
          get type() {
              return Employee.legalTypeCodes[this._typeCode];
          }
          static get legalTypeCodes() {
              return {"E": "Engineer", "M": "Manager", "S": "Salesperson"};
          }
      }
  • Employee 클래스를 사용하는 코드
    • // 호출자 1
      candidate = new Employee(document.name, document.empType);
      
      // 호출자 2
      const leadEngineer = new Employee(document.leadEngineer, 'E');
       
  • [Step 1] 팩터리 함수 만들기
    • 팩토리 본문은 단순히 생성자에 위임하는 방식으로 구현한다.
    • function createEmployee(name, typeCode) {
          return new Employee(name, typeCode);
      }
  • [Step 2] 생성자를 호출하는 곳을 찾아 수정한다.
    • // 호출자 1
      candidate = createEmployee(document.name, document.empType);
      
      // 호출자 2
      const leadEngineer = createEmployee(document.leadEngineer, 'E');
    • 함수에 문자열 리터럴을 건네는 건 악취로 봐야 한다. 
    • 그 대신 직원 유형을 팩토리 함수의 이름에 녹이는 방식이 더 좋다.
    • function createEngineer(name) {
          return new Employee(name, 'E');
      }

 

 

출처:

- [리팩터링 2판]

반응형
Comments