본문 바로가기

Domain/디자인패턴

[디자인패턴] 템플릿 메소드 패턴(Template Method Pattern)

템플릿 메소드 패턴(Template Method Pattern)

작업을 처리하는 일부분을 서브 클래스로 캡슐화하여 전체 일을 수행하는 구조는 변동이 없고, 특정 단계에서 수행하는 내용을 바꾸는 패턴이다. 즉, 알고리즘의 구조를 변경하지 않고 알고리즘의 특정 단계를 다시 정의할 수 있게 해준다.

위 구조를 보면 부모 클래스인 AlgorithmBase에서 전반적인 과정을 수행하는 TemplateMethod()가 존재하고, 그 외에 세부 메서드인  Step1(), Step2(), Step3()가 존재한다. TemplateMethod()에서는 해당 세부 메서드를 수행하게 된다. 그리고 자식 클래스인 ConcreateAlgorithmA,B는 이를 상속 받는다.

 

 

피자 만들기 예시

한 마을에서 피자 달인인 밥 아저씨가 존재한다. 밥 아저씨는 본인이 죽기 전에 다니엘과 루크에게 각각 서로 다른 피자레시피를 알려주었다. 피자를 만드는 과정은 같으나 피자를 굽는 시간, 준비된 재료가 다르다. 그 외의 피자 8등분으로 자르기, 도우 만들기의 과정은 같다고 한다.

 

상위 클래스

abstract class PizzaTemplate{
    public final void makePizza(){
    	makeDow();
        useIngredient();
        bakePizza();
        devidePizza();
    }
    private void makeDow(){
    	System.out.println("도우 만들기");
    }
    
    public abstract void useIngredient();
    public abstract void bakePizza();
    
    private void devidePizza(){
    	System.out.println("피자 8등분");
    }
}

세부 단계인 makeDow()와 devidePizza()의 과정은 어느 하위 클래스든 동일한 작업을 하게 된다.

 

하위 클래스

abstract class DanielPizza extends PizzaTemplate{
    @override
    public void useIngredient(){
    	System.out.println("양파,토마토,치즈,불고기")
    }
    @override
    public void bakePizza(){
    	System.out.println("180도에서 10분 간 굽기")
    }
}

abstract class LookePizza extends PizzaTemplate{
    @override
    public void useIngredient(){
    	System.out.println("양파,피망,치즈,핫치킨")
    }
    @override
    public void bakePizza(){
    	System.out.println("200도에서 9분 간 굽기")
    }
}

 

실제 활용

public class Example{
    public static void main(String[] args){
    	new DanielPizza().makePizza()
        new Looke().makePizza()
    }
}

실제 더 그럴듯한 예제는 '얄팍한 코딩사전'님의 '객체지향 디자인패턴 2'에서 보는게 좋을 것 같다. 해당 영상에서는 탭뷰를 가진 앱에서 네이버맵, 카카오맵을 각각 로드하는 과정을 예시로 다룬다.

 

요약

  • 전체적인 알고리즘 과정은 같으나 과정 속 세부 단계에서 다를 경우 활용
  • 상위 클래스에서 각 단계를 선언하고, 해당 단계를 호출하는 템플릿 메서드를 정의한다.
  • 하위 클래스는 상위 클래스를 상속 받아 각 단계를 오버라이딩한다.