템플릿 메서드 패턴
상위 클래스에서는 동작상의 알고리즘의 뼈대를 정의하고 그 구현을 서브 클래스에서 하는 패턴
- 템플릿 메서드를 이용하면 알고리즘의 구조는 그대로 유지하면서 서브 클래스에서 특정 단계를 재정의할 수 있다.
- AbstractClass의 templateMethod()에는 알고리즘의 골격이 정의되어 있다.
- 모든 객체들이 공통으로 수행하는 작업은 AbstractClass에서 수행한다.
- 그 후 나머지는 abstract 메서드로 구현하여 서브 클래스에서 구현하게 만든다.
예제
AbstractClass
public abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
// hook
if (wantCondiments()){
addCondiments();
}
}
private void boilWater() {
System.out.println("물 끓이는 중");
}
protected abstract void brew();
private void pourInCup() {
System.out.println("컵에 따르는 중");
}
protected abstract void addCondiments();
protected boolean wantCondiments() {
return true;
}
}
- AbstractClass에서는 boilWater와 pourInCup은 서브클래스들의 공통된 과정이라고 생각하고 여기서 직접 구현하였다.
- 서로 다른 동작을 하는 메서드들은 추상 메서드로 구현하였다.
- 모든 메서드들의 수행이 들어 있는 final로 구현된 prepareRecipe가 templateMethod이다.
- 메서드 내부에 메서드들의 순서가 정해져 있고 final로 구현되었기 때문에 하위 클래스에서는 이 메서드를 오버라이드 할 수 없다.
Hook
- if 문안에 있는 wantCondiments()이 hook이다.
- hook을 통해 서브 클래스에서 동작을 수행할지 결정할 수 있다.
- 부모 클래스에서 wantCondiments은 true를 리턴한다.
- 만약 하위 클래스에서 addCondiments를 원하지 않는다면 wantCondiments를 오버라이드 하여 false를 리턴하면 된다.
ConcreteClass
public class Coffee extends CaffeineBeverage {
@Override
protected void brew() {
System.out.println("커피를 내리는 중");
}
@Override
protected void addCondiments() {
System.out.println("설탕을 추가하는 중");
}
}
public class Tea extends CaffeineBeverage {
@Override
protected void brew() {
System.out.println("차를 우리는 중");
}
@Override
protected void addCondiments() {
System.out.println("레몬을 추가하는 중");
}
@Override
protected boolean wantCondiments() {
return false;
}
}
- ConcreteClass들로 부모 클래스에서 추상 메서드로 작성한 것들을 구현한다.
- Tea는 hook인 wantCondiments를 따로 구현하여 false를 반환한다.
- Tea에서는 addCondiments가 동작하지 않을 것이다.
Test
public class Main {
public static void main(String[] args) {
Coffee coffee = new Coffee();
Tea tea = new Tea();
coffee.prepareRecipe();
System.out.println("=============================");
tea.prepareRecipe();
}
}
물 끓이는 중
커피를 내리는 중
컵에 따르는 중
설탕을 추가하는 중
=============================
물 끓이는 중
차를 우리는 중
컵에 따르는 중
- 결과를 확인해보면 정해진 단계별로 잘 출력이 되는 것을 알 수 있다.
- Tea는 hook을 통해 addCondiments를 실행하지 않기로 하였기 때문에 템플릿 메서드들 실행하여도 addCondiments가 실행되지 않았다.
'디자인 패턴' 카테고리의 다른 글
컴포지트 패턴(Composite Pattern) (0) | 2019.12.20 |
---|---|
이터레이터 패턴(Iterator Pattern) (0) | 2019.12.17 |
퍼사드 패턴(Facade Pattern), 최소 지식 원칙 (0) | 2019.12.16 |
어댑터 패턴(Adapter Pattern) (0) | 2019.12.16 |
커맨드 패턴(Command Pattern) (0) | 2019.12.14 |