✏️10.4 조건부 로직을 다형성으로 바꾸기 (Replace Conditional with Polymorphism)
리팩터링 전
switch (bird.type) {
  case '유럽 제비':
    return "보통이다";
  case '아프리카 제비':
    return (bird.numberOfCoconuts > 2) ? "지쳤다" : "보통이다";
  case 'NorwegianBlueParrot':
    return (bird.voltage > 100) ? "그을렸다" : "예쁘다";
  default:
    return "알 수 없다";리팩터링 후
class EuropeanSwallow {
  get plumage() {
    return "보통이다";
  }
  ...
class AfricanSwallow {
  get plumage() {
     return (this.numberOfCoconuts > 2) ? "지쳤다" : "보통이다";
  }
  ...
class NorwegianBlueParrot {
  get plumage() {
     return (this.voltage > 100) ? "그을렸다" : "예쁘다";
  }🧷 배경
조건문을 클래스와 다형성을 이용하면 더 확실하게 분리할 수 있다.
기본 로직을 슈퍼클래스로 넣어서 서브클래스의 변형 동작에 신경 쓰지 않고 기본에 집중하게 할 수 있게 한다.
🧷 절차
- 다형적 동작을 표현하는 클래스들이 아직 없다면 만들고 팩터리 함수도 함께 만든다. 
- 호출하는 코드에서 팩터리 함수를 사용하게 한다. 
- 조건부 로직 함수를 슈퍼클래스로 옮긴다. 
- 서브클래스 중 하나를 선택하여, 슈퍼클래스의 조건부 로직 메서드를 오버라이드한다. 
- 같은 방식으로 각 조건절을 해당 서브클래스에서 메서드로 구현한다. 
- 슈퍼클래스 메서드에는 기본 동작 부분만 남긴다. 
🧷 예시
🧷 리팩터링 전
function plumages(birds) {
  return new Map(birds.map((b) => [b.name, plumage(b)]));
}
function speeds(birds) {
  return new Map(birds.map((b) => [b.name, airSpeedVelocity(b)]));
}
function plumage(bird) {
  switch (bird.type) {
    case '유럽 제비':
      return '보통이다';
    case '아프리카 제비':
      return bird.numberOfCoconuts > 2 ? '지쳤다' : '보통이다';
    default:
      return '알 수 없다';
  }
}
function airSpeedVelocity(bird) {
  switch (bird.type) {
    case '유럽 제비':
      return 35;
    case '아프리카 제비':
      return 40 - 2 * bird.numberOfCoconuts;
    default:
      return null;
  }
}🧷 리팩터링 후
function plumages(birds) {
  return new Map(birds
                .map((b) => createBird(b))
                .map((bird) => [bird.name, bird.plumage]));
}
function speeds(birds) {
  return new Map(birds
                .map((b) => createBird(b))
                .map((bird) => [bird.name, bird.airSpeedVelocity]));
}
class Bird {
  constructor(birdObject) {
    Object.assign(this, birdObject);
  }
  get plumage() {
    return '알 수 없다';
  }
  get airSpeedVelocity() {
    return null;
  }
}
class EuropeanSwallow extends Bird {
  get plumage() {
    return '보통이다';
  }
  get airSpeedVelocity() {
    return 35;
  }
}
class AfricanSwallow extends Bird {
  get plumage() {
    return this.numberOfCoconuts > 2 ? '지쳤다' : '보통이다';
  }
  get airSpeedVelocity() {
    return 40 - 2 * this.numberOfCoconuts;
  }
}
function createBird(bird) {
  switch (this.type) {
    case '유럽 제비':
      return new EuropeanSwallow(bird);
    case '아프리카 제비':
      return new AfricanSwallow(bird);
    default:
      return new Bird(bird);
  }
}Previous10.3 중첩 조건문을 보호 구문으로 바꾸기 (Replace Nested Conditional with Guard Clauses)Next10.5 특이 케이스 추가하기 (Introduce Special Case)
Last updated