상속 다루기

12.1 메서드 올리기

class Employee { ... }

class Salesperson extends Employee {
	get name() { ... }
}

class Engineer extends Employee {
	get name() { ... }
}

class Employee {
	get name() { ... }
} 

class Salesperson extends Employee { ... }
class Engineer extends Employee { ... }

배경

메서드 올리기는 보통 중복된 코드를 제거할 때 사용된다

메서드들끼리 본문 코드가 똑같을 때, 메서드 올리기를 사용하기 가장 적절하고 쉽지만 리팩터링이 제대로 되었는지 알기 위해선 좋은 테스트를 거쳐야 하는 것이 까다롭다 ⇒ 테스트보다 먼저 차이점을 찾는 방법이 효과가 좋다

메서드 올리기 리팩터링을 적용하려면 선행 단계를 거쳐야 할 때가 많다

예를 들면 서로 다른 클래스의 메서드들을 각각 매개변수화하면 궁극적으로 같은 매개변수가 되기도 한다

이렇게 되었을 경우 각각의 함수를 매개변수화한 다음 메서드를 상속 계층의 위로 올리면 좋다

반면 메서드 올리기 가장 이상하고 복잡한 상황은 메서드의 본문에서 참조하는 필드들이 서브클래스에만 있는 경우이다 ⇒ 이런 경우 필드를 먼저 슈퍼클래스로 올린 뒤 메서드를 올려주어야 한다

메서드의 전체 흐름은 비슷하지만 세부 내용이 다르다면 템플릿 메서드 만들기 (https://refactoring.com/catalog/formTemplateMethod.html) 을 고려해보자

절차

  1. 똑같이 동작하는 메서드인지 잘 살펴본다
  2. 메서드 안에서 호출하는 다른 메서드와 참조하는 필드들을 슈퍼클래스에서도 호출하고 참조할 수 있는지 확인한다
  3. 메서드 시그니처가 다르다면 함수 선언 바꾸기로 슈퍼클래스에서 사용하고 싶은 형태로 통일한다
  4. 슈퍼클래스에 새로운 메서드를 생성하고, 대상 메서드의 코드를 복사해넣는다
  5. 정적 검사를 수행한다
  6. 서브클래스 중 하나의 메서드를 제거한다
  7. 테스트한다
  8. 모든 서브클래스의 메서드가 없어질 때까지 다른 서브클래스의 메서드를 하나씩 제거한다