본문으로 바로가기

Template method pattern

category Helloworld!/Design Pattern & Algorithm 2013. 10. 20. 23:32

template(틀) pattern 


상황 : 쉐킹이라는 까페에서는 커피와 홍차를 만들 때 다음과 같은 레시피를 사용한다.


1. 커피를 만들때

 - 물을 끓인다

 - 끓는 물에 커피를 우려낸다

 - 커피를 컵에 따른다

 - 설탕과 우유를 추가한다

 

 2. 홍차를 만들때

 - 물을 끓인다

 - 끓는 물에 차를 우려낸다

 - 차를 컵에 따른다

 - 레몬을 추가한다

 

이 두개의 레시피의

차이점 : 무슨 음료를 만들지, 마지막으로 어떤 재료를 추가할지만 다르고

공통점 : 물을 끓이고, 음료(커피나 차)를 컵에 따르는 것은 같은 방법을 사용

 

따라서, 어떤 음료를 우려내는지(brew), 마지막에 어떤 재료를 추가할지(addCondiments)는

추상메소드로 선언하고 서브클래스에서 알아서 하도록 함





template.php

abstract class shakingCafe{

    //음료를 만드는 방법 알고리즘으로 정의 후 final로 템플릿화 시킴
    public final function prepareRecipe(){
        $this->boilWater();     //물을 끓인다
        $this->brew();          //음료를 우려낸다
        $this->pourInCup();     //음료를 컵에 따른다
        $this->addCondiments(); //마지막 첨가물을 넣는다
    }

    protected abstract function brew(); //커피와 차가 다른 부분은 각 단계에서 재정의

    protected abstract function addCondiments(); //커피와 차가 다른 부분은 각 단계에서 재정의

    protected function boilWater(){
        echo "물을 끓이는 중 \n";
    }

    protected function pourInCup(){
        echo "컵에 음료를 따르는 중 \n";    
    }
}
* 참고 :  final 클래스 는 override 함수나 상속 불가. 다른 클래스에서 확장할 수 없음
레시피 메소드를 추상 클래스 안에 선언 후 음료를 우려내는 함수(blew)와 첨가물을 넣는 함수(addCondiments)를 다시 추상화 함수로 선언하여 다음과 같이 다시 서브 클래스를 사용한다.

coffee.php
include_once('template.php');

class Coffee extends shakingCafe{
    public function brew(){
        echo "커피를 우려낸다 \n";
    }

    public function addCondiments(){
        echo "설탕과 우유를 넣는다\n";
    }
}
tea.php
include_once('template.php');

class Tea extends seafutureCafe{
    public function brew(){
        echo "홍차를 우려낸다 \n";
    }

    public function addCondiments(){
        echo "레몬을 넣는다 \n";
    }
}
출력! shakingCafe.php
include_once('template.php');
include_once('tea.php');
include_once('coffee.php');

$tea = new Tea();
$coffee = new Coffee();

echo "[coffee] \n";
$coffee->prepareRecipe();
echo "\n";

echo "[tea] \n";
$tea->prepareRecipe();
echo "\n";


참고사이트 :
http://idhana.com/2011/11/22/design-pattern-template-in-php/ (hook를 사용하는 예시도 있음)
http://cafe.naver.com/junes81/382 (hook를 사용하는 예시도 있음)

http://cafe.naver.com/hopegiver/48