기록하자..
템플릿 메서드 패턴 (Template Method Pattern) 본문
템플릿 메서드 패턴
메서드의 알고리즘의 골격을 정의하며 알고리즘의 일부 단계는 하위 클래스에서 구현할 수 있다. 이 패턴은 알고리즘의 구조를 변경하지 않고 하위 클래스에서 알고리즘의 일부 단계를 변경할 수 있게 해준다.
Head First Design Pattern에서는 커피와 차(tea)를 만드는 과정을 비교하며 이 패턴을 설명하고 있다.
public class Coffee {
public void prepareRecipe() {
boilWater();
brewCoffeeGrinds();
pourInCup();
addSugarAndMilk();
}
public void boilWater() {}
public void brewCoffeeGrinds() {}
public void pourInCup() {}
public void addSugarAndMild() {}
}
public class Tea {
public void prepareRecipe() {
boilWater();
steepTeaBag();
pourInCup();
addLemon();
}
public void boilWater() {}
public void steepTeaBag() {}
public void pourInCup() {}
public void addLemon() {}
}
두 클래스에서 비슷한 부분들이 보인다. 비슷한 부분을 따로 상위클래스로 만들어 중복을 줄일 수 있지 않을까?
steepTeaBag과 brewCoffeeGrinds를 brew로 묶고, addSugarAndMilk와 addLemon을 addCondiments로 묶어서 만들어보자.
public abstract class CaffeineBeverage {
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
public final void boilWater() {}
public abstract void brew();
public final void pourInCup() {}
public abstract void addCondiments();
}
알고리즘의 골격을 변경할 수 없도록 final 메서드로 선언하고 하위클래스에 따라 달라지는 부분은 하위클래스에서 제공하도록 추상메서드로 선언한다.

그럼 이제 템플릿 메서드 패턴의 구조를 살펴보자.

- template method (templateMethod) : 메서드들의 알고리즘 골격을 정의하고 있는 메서드
- abstract method (primitiveMethod) : Template메서드가 선언되어 있는 클래스에 선언만 되어있고 내용은 정의되지 않은 메서드로 하위 클래스에서 반드시 재정의해야하는 메서드
- concrete method (concreteMethod) : Template메서드가 선언되어 있는 클래스에 완전히 정의가 되어있는 메서드로 하위클래스에서 재정의하지 말아야 할 메서드
- hook method (hookMethod) : Template메서드가 선언되어 있는 클래스에 기본행동이 정의되어 있는 메서드로 하위클래스는 이를 선택적으로 재정의 할 수 있는 메서드
- 빈 메서드로 정의될 수 있다. (해당 단계는 건너 뛸 수 있다는 소리)
Hook 메서드
추상 클래스에 정의되는 메서드로서, template 메서드를 통해 정의되는 알고리즘의 단계 중 하위 클래스가 선택적으로 재정의할 수 있는 메서드
public abstract class CaffeineBeverage {
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if(customerWantsCondiments())
addCondiments();
}
pubilc final void boilWater();
public abstract void brew();
public final void pourInCup() {}
public abstract void addCondiments();
public boolean customerWantsCondiments() {
return true;
}
}
hook 메서드를 재정하지 않으면 abstract class에서 기본 행동이 정의되어 있어 실행이 된다. hook 메서드는 빈 메서드로 재정의 해도 된다. (그런데, customerWantsCondiments()의 return 값이 false이더라도 재정의 해줘야 한다는 문제점이 있다...)
장단점
- 장점
- 자식 클래스의 확장을 제한할 수 있다.
- 코드의 중복을 줄일 수 있다.
- 단점
- 알고리즘의 고정된 골격에 의해 유연성이 떨어질 수 있다.
'디자인패턴공부' 카테고리의 다른 글
| 어댑터 & 퍼사드 패턴 (Adapter & Facade Pattern) (0) | 2021.12.02 |
|---|---|
| 명령 패턴(Command Pattern) (0) | 2021.11.28 |
| 생성 패턴(Factory Pattern) (0) | 2021.11.28 |
| Decorator 패턴 (0) | 2021.10.26 |
| 관찰자 패턴(Observer Pattern) (0) | 2021.10.19 |