템플릿 메소드(Template Method) 패턴은 알고리즘의 뼈대는 부모 클래스에 정의하고, 알고리즘의 세부적인 단계는 자식 클래스에서 구현하도록 하는 디자인 패턴입니다. 이렇게 하면 알고리즘의 구조는 고정된 채, 세부 구현만 변경할 수 있어 코드 재사용성과 유연성을 제공합니다.
커피와 차를 만드는 예시를 보면, 물 끓이기와 컵에 따르기와 같은 과정은 공통이고, 커피 내리기와 티백 우리기, 첨가물 추가는 다릅니다. 코드 중복을 줄이고, 나중에 전체 로직을 수정할 때 불편함을 없애려면, 공통된 로직을 따로 빼놓고 각자 다른 부분만 구현하도록 해야 합니다.
추상 클래스 (AbstractClass)
templateMethod(): 알고리즘의 뼈대. 각 단계는 메소드 호출로 연결됩니다. 보통 final로 선언하여 자식 클래스에서 변경할 수 없도록 합니다.primitiveOperation(): 자식 클래스가 구현해야 하는 추상 메소드들.hook(): 자식 클래스가 선택적으로 오버라이드할 수 있는 메소드.구체 클래스 (ConcreteClass)
abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("물을 끓이는 중");
}
void pourInCup() {
System.out.println("컵에 따르는 중");
}
boolean customerWantsCondiments() {
return true;
}
}
class Coffee extends CaffeineBeverage {
@Override
void brew() {
System.out.println("커피를 내리는 중");
}
@Override
void addCondiments() {
System.out.println("설탕과 우유를 추가하는 중");
}
}
class Tea extends CaffeineBeverage {
@Override
void brew() {
System.out.println("찻잎을 우려내는 중");
}
@Override
void addCondiments() {
System.out.println("레몬을 추가하는 중");
}
}
final로 선언해 알고리즘의 흐름을 강제할 수 있습니다.hook() 메소드를 사용해 알고리즘 중 특정 단계를 선택적으로 변경할 수 있습니다.템플릿 메소드 패턴은 알고리즘의 뼈대는 부모 클래스에서 관리하고, 세부 구현만 자식 클래스에서 수정하도록 하는 매우 유용한 패턴입니다. 이를 통해 코드 중복을 줄이고, 일관된 구조를 유지하면서 유연한 확장이 가능합니다.