구체적인 구현은 다르나 기본적인 알고리즘의 골격이 비슷하거나 같을 때 사용하는 패턴으로 공통된 부분(알고리즘의 구조)을 상위 클래스에서 정의하고 서브 클래스에서 일부 단계를 오버라이딩함으로 알고리즘의 일부를 변경할 수 있는 패턴이다.
카페에서 아메리카노와 라떼는 만드는 상황이라 하자.
1. Cafe 클래스는 makeAmericano와 makeLatte를 통해 아메리카노와 라떼를 만든다.
public class Cafe {
public void makeAmericano() {
boilWater();
brewCoffeeBeans();
pourInCup();
addWater();
addIngredients();
}
public void makeLatte() {
boilWater();
brewCoffeeBeans();
pourInCup();
addMilk();
addIngredients();
}
public void boilWater() {
System.out.println("Boiling water");
}
public void brewCoffeeBeans() {
System.out.println("Brewing coffee beans");
}
public void pourInCup() {
System.out.println("Pouring into cup");
}
public void addWater() {
System.out.println("Adding water");
}
public void addMilk() {
System.out.println("Adding milk");
}
public void addIngredients() {
System.out.println("Adding sugar and cream");
}
}
위 상황에서 아메리카노를 만드는 과정과 라떼는 만드는 과정을 보면
1. 물을 끓인다.
2. 커피원두를 우린다.
3. 컵에 넣는다.
4-1. 아메리카노는 물을 더 넣는다.
4-2. 라떼는 우유를 넣는다.
5. 추가 재료를 넣는다.
같은 구조가 반복된다. 즉, 대부분의 단계가 같고 추가 재료를 넣는 단계만 다르며 이러한 상황에서 코드의 중복이 발생하고 물을 끊이는 방법이나 커피원두를 우리는 방법이 변경된다면 makeAmericano와 makeLatte의 코드를 수정해야 한다.
공통 단계에 해당하는 부분을 묶에 상위 클래스에서 정의하자
1. Cafe
public abstract class Coffee {
public void prepareCoffee() {
boilWater();
brewCoffeeBeans();
pourInCup();
addIngredients();
}
public void boilWater() {
System.out.println("Boiling water");
}
public void brewCoffeeBeans() {
System.out.println("Brewing coffee beans");
}
public void pourInCup() {
System.out.println("Pouring into cup");
}
abstract void addIngredients();
}
2. Americano
public class Americano extends Coffee {
public void addIngredients() {
System.out.println("Adding water");
System.out.println("Adding sugar and cream");
}
}
3. Latte
public class Latte extends Coffee {
public void addIngredients() {
System.out.println("Adding milk");
System.out.println("Adding sugar and cream");
}
}
설탕과 크림을 넣는다라는 재료를 넣는 함수는 공통된 부분이다. 만약, 모든 커피 종류에 공통으로 설탕과 크림을 넣는다라는 기능이 겹친다면 이부분 역시 상위 클래스로 넣을 수 있다.
전략 패턴과 달리 템플릿 메소드 패턴은 알고리즘의 일부만 변경한다. 템플릿 메소드 패턴은 상속관계를 이용해 알고리즘의 일부를 바꾸고 전략패턴은 위임을 이용해 알고리즘 전체를 바꾼다.