09. Template Method Pattern

알고리즘의 뼈대를 정의하고 일부를 서브 클래스로 위임한다.
알고리즘 구조를 변경하지 않고 알고리즘의 일부 내용을 서브 클래스에서 재정의 할 수 있도록 한다.

Problem

  • 알고리즘들을 캡슐화시키면서 중복되는 코드가 여러 클래스에 존재
  • ex) 커피 만드는 법 (물을 끓인다. 끓는 물에 커피를 우려낸다.) , 차 만드는 법(물을 끓인다. 끓는 물에 차를 우려낸다.)

Solution

  • 알고리즘의 중복되는 부분을 부모 클래스에 캡슐화 시키고 달라지는 부분만 서브 클래스에서 구현하도록 한다.

예시1 - 스타버즈 커피

: 레시피 중에서 특정 부분은 같고, 특정 부분만 다를 수 있다.

  • 예를 들어, 커피와 홍차 만드는 방법을 추상화 한다면
  1. 물을 끓인다.
  2. 뜨거운 물을 이용하여 커피 또는 홍차를 우려낸다.
  3. 만들어진 음료를 컵에 따른다.
  4. 각 음료에 맞는 첨가물을 추가한다.
public final void prepareRecipe(){ //final: overriding 못하도록 한다.
    voilwater();
    brew();
    pourInCup();
    addCondiments();
}
  • 위의 코드를 추가해서 Beverage라는 abstract class를 생성할 수 있다.
  • 커피와 홍차는 abstract class를 상속 받아, 각자의 클래스에 맞게 구현할 수 있다.

예시2 - hook() 이용

template method

public abstract class CaffeineBeverageWithHook {
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments(); 
        }
    }
    public abstract void brew();
    public abstract void addCondiments();
    public void boilWater() {
        System.out.println("물 끓이는 중"); }
    public void pourInCup() {
        System.out.println("컵에 따르는 중"); }
    boolean customerWantsCondiments() { // Hook
        return true;
    }
}
  • Hook() : 기본적인 내용만 구현되어 있거나 아무 코드도 들어있지 않은 메소드 / 호출이 안돼도 상관없는 코드

Concrete Class

public class CoffeeWithHook extends CaffeineBeverageWithHook {
    public void brew() {
        System.out.println("필터로 커피를 우려내는 중");
    }

    public void addCondiments() {
        System.out.println("우유와 설탕을 추가하는 중");
    }

    public boolean customerWantsCondiments() {
        char answer = getUserInput();
        return (answer == 'y') ? true : false;
    }

    public char getUserInput() {
        String answer = null;
        Scanner sc = new Scanner(System.in);
        System.out.println("커피에 우유와 설탕을 추가하시겠습니까?");
        answer = sc.next();
        return answer.charAt(0);
    }
}

정리

  • 템플릿 메소드에서 알고리즘의 골격을 정의한다.
  • 템플릿 메소드를 이용하면 알고리즘의 구조는 유지하면서 서브 클래스에서 특정 단계를 새로 정의가 가능하다.

좋은 웹페이지 즐겨찾기