The Template Method Pattern
2023. 10. 22. 01:05ㆍ디자인패턴
728x90
Template Method Pattern
:메소드에서 알고리즘의 뼈대를 정의하고, 구현은 서브클래스에서 하도록 하는 방법.
상속을 통해 슈퍼클래스의 기능을 확장할 때 사용하는 대표적인 방법.
변하지 않는 기능은 슈퍼클래스에 만들어주고
자주 변경되며 확장할 기능은 서브클래스에 만들어준다.
여러 작업들이 동일한 동작을 하지만, 일부 동작은 다르게 구현해야 할 때 사용되는 패턴.
예시)
커피 만드는 클래스
public class Coffee {
void prepareRecipe() {
boilWater();
brewCoffeeGrinds();
pourInCup();
addSugarAndMilk();
}
public void boilWater() {
System.out.println(“Boiling water”);
}
public void brewCoffeeGrinds() {
System.out.println(“Dripping Coffee through filter”);
}
public void pourInCup() {
System.out.println(“Pouring into cup”);
}
public void addSugarAndMilk() {
System.out.println(“Adding Sugar and Milk”);
}
}
티 만드는 클래스
public class Tea {
void prepareRecipe() {
boilWater();
steepTeaBag();
pourInCup();
addLemon();
}
public void boilWater() {
System.out.println(“Boiling water”);
}
public void steepTeaBag() {
System.out.println(“Steeping the tea”);
}
public void addLemon() {
System.out.println(“Adding Lemon”);
}
public void pourInCup() {
System.out.println(“Pouring into cup”);
}
}
이 두 클래스는 아래 표시된 두 메소드만 다르다.

두 클래스의 슈퍼클래스를 추상 클래스로 만들어보자

public abstract class CaffeineBeverage {
final void prepareRecipe() { //서브클래스가 사용가능하도록 final 키워드 사용
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew(); //서브클래스에서 변경 가능하도록 abstract로 정의
abstract void addCondiments(); //서브클래스에서 변경 가능하도록 abstract로 정의
void boilWater() {
System.out.println(“Boiling water”);
}
void pourInCup() {
System.out.println(“Pouring into cup”);
}
}
public class Tea extends CaffeineBeverage {
public void brew() {
System.out.println(“Steeping the tea”);
}
public void addCondiments() {
System.out.println(“Adding Lemon”);
}
}
public class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println(“Dripping Coffee through filter”);
}
public void addCondiments() {
System.out.println(“Adding Sugar and Milk”);
}
}
Hook
: 추상클래스에서 선언되는 메소드
기본적인 내용만 구현되어 있거나 아무 코드도 들어있지 않은 메소드
public abstract class CaffeineBeverageWithHook {
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println(“Boiling water”);
}
void pourInCup() {
System.out.println(“Pouring into cup”);
}
boolean customerWantsCondiments() {
//이 메소드는 서브클래스에서 필요에 따라 override 할 수 있는 hook이다.
return true;
}
}
서브클래스에서 구현하여 사용
public class CoffeeWithHook extends CaffeineBeverageWithHook {
public void brew() {
System.out.println(“Dripping Coffee through filter”);
}
public void addCondiments() {
System.out.println(“Adding Sugar and Milk”);
}
public boolean customerWantsCondiments() {
String answer = getUserInput();
if (answer.toLowerCase().startsWith(“y”)) {
return true;
}
else {
return false;
}
}
private String getUserInput() {
...
}
The Hollywood Principle
: 상위레벨에서 하위레벨은 호출가능하지만
하위레벨이 상위레벨을 호출하면 안됨

서브클래스들은 추상클래스를 호출하지 않는다.
추상클래스는 서브클래스를 호출한다.
-> 전체 시스템의 의존성이 줄어든다.
728x90
'디자인패턴' 카테고리의 다른 글
| composite pattern (0) | 2023.10.30 |
|---|---|
| The iterator pattern (0) | 2023.10.22 |
| The Adapter and Facade Patterns (0) | 2023.10.21 |
| The Command Pattern (1) | 2023.10.21 |
| The Singleton Pattern (1) | 2023.10.21 |