하위클래스 안의 두 메서드가 거의 비슷한 단계들을 같은 순서로 수행할 땐
그 단계들을 시그니처가 같은 두 개의 메서드로 만들어서 두 원본 메서드를 같게 만든 후,
두 메서드를 상위클래스로 옮긴다
동기
- 하위 클래스에 있는 두 메서드가 비슷하다면 둘을 합쳐서 하나의 상위 클래스로 만드는것이 좋다
- 두 메서드가 완전히 똑같지 않다면, 중복된 부분은 가능한 한 전부 없애고 차이가 있는 필수 부분만 그대로 둬야한다
방법
-
비슷해보이는 같은 클래스에 있다면, 두 메서드가 어떤 공통 상위클래스의 하위클래스가 되게 정리해야 한다
1
2
3
4
5
6
7
8
9class Printer {
public String textPrint() {
// ...
}
public String imagePrint() {
// ...
}
}를 아래의 구조로 변경한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Printer {
public String textPrint() {
return new TextPrinter().print();
}
public String imagePrint() {
return new ImagePrinter().print();
}
}
class TextPrinter extends Printer {
public String print() {
// ...
}
}
class ImagePrinter extends Printer {
public String print() {
// ...
}
}- 리팩토링은 작게작게 진행해야하므로, 하위클래스에 위임하는 방식으로 구현했다
- 메서드상향이 용이하도록 두 하위클래스의 메서드명을 같게했다
-
두 메서드를 잘게 분리하는데, 공통된 부분과 공통되지 않은 부분이 나오게끔 분리한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class TextPrinter extends Printer {
public String print() {
// ...
printBody();
// ...
}
public String printBody() {
// 다른 부분
}
}
class ImagePrinter extends Printer {
public String print() {
// ...
printBody();
// ...
}
public String printBody() {
// 다른 부분
}
}이 기법의 핵심이다
-
하나의 클래스에 대해 메서드 상향을 실시하자
1
2
3
4
5
6
7
8
9
10
11
12
13abstract class Printer {
public String print() {
// ...
printBody();
// ...
}
public abstract String printBody(); // 달랐던 부분
}
class TextPrinter extends Printer {
public String printBody() {
// 다른 부분
}
}- 달랐던 부분은
abstract
로 선언하고, 하위클래스에서 구현하도록 한다 - 위임하던 코드는 삭제한다
- 달랐던 부분은
-
나머지 하나의 클래스에도 동일하게 적용한다
참고 : 마틴 파울러, 『리팩토링』, 김지원 옮김, 한빛미디어(2012)