Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Template method pattern

behavioral pattern이라고 부르기도 한다. C++의 template와는 아무런 상관이 없다.

상위 클래스, 즉 base 클래스는 기본적인 메서드만 제공하고 base 클래스로 부터 파생된 클래스에서 해당 메서드를 제정의 해서 사용한다. 만약 해당 메서드를 재정의 하지 않는다면, 기본 메서드를 그대로 사용한다.

Template method pattern을 사용한 가장 대표적인 예는 C(:12)의 qsort(3) 함수일 것이다. qsort는 내부에 quick:::sort(:12)알고리즘만 가지고 있으며, 정렬하고자 하는 원소를 비교할 알고리즘을 함수포인터를 이용해서 정의할 수 있도록 해놓았다. 이렇게 함으로써, 프로그래머는 다양한 타입의 원소에 대응되는 정렬 프로그램을 만들 수 있다.

C++, Java(:12)같은 객체지향 언어에서는 다형성을 이용해서 좀더 직관적으로 구현할 수 있을 것이다.

이 패턴은 알고리즘을 다양하게 정의 할수 있으며, 알고리즘을 어떻게 정의하느냐에 따라서 다양한 결과물을 만들어낼 수 있다. 이 결과물은 응용 애플리케이션에서 view가 될 수 있을 것인데, 여기에서 template method pattern은 MVC(:12)패턴의 서브셋이 됨을 알 수 있다.

예제

C++

sort프로그램을 만드는게 가장 좋을 것 같기는하다. base 클래스는 sort알고리즘을 가지고, compare메서드에서 비교알고리즘을 가지도록 하는 식이다. 그러나 예제로 사용하기에는 귀찮은 감이 있으니 아주 심플한 예제를 준비했다. 나중에 좀더 그럴듯한 예제를 만들어봐야지 싶다.
#include <iostream>

using namespace std;

class Base
{
    void a()
    {
        cout << "a  ";
    }
    void c()
    {
        cout << "c  ";
    }
    void e()
    {
        cout << "e  ";
    }

    virtual void ph1() = 0;
    virtual void ph2() = 0;
  public:

    void execute()
    {
        a();
        ph1();
        c();
        ph2();
        e();
    }
};

 

class One: public Base
{
    void ph1()
    {
        cout << "b  ";
    }
    void ph2()
    {
        cout << "d  ";
    }
};

class Two: public Base
{
    void ph1()
    {
        cout << "2  ";
    }
    void ph2()
    {
        cout << "4  ";
    }
};

int main()
{
  Base *array[] = 
  {
     &One(), &Two()
  };

  for (int i = 0; i < 2; i++)
  {
    array[i]->execute();
    cout << '\n';
  }
}
결과
# ./sort
a  b  c  d  e  
a  2  c  4  e  

php

여기에서는 MVC(:12)의 서브셋으로써의 template method 패턴의 사용예를 들었다. 이 패턴은 개인 프로젝트인 dmf 프레임워크에 사용되었다.
// base class
// interface를 이용해서 순수가상함수로 만들 수도 있을 것이다.
class Module
{
	var $options;	
	var $template
	function model()
	{
		echo "This is model method";
	}
	function view()
	{
		echo "This is view";
	}
}

class dbtest extends Module
{
  var $className = 'dbtest';
  var $viewData;
  function model()
  {
    $DBI = $this->formatter[db];
    if(isset($this->options[searchstr]))
    {
      $str = $this->options[searchstr];
      $DBI->Query("select id, subject, ip from joinc_Trackbacks where subject like '%$str%'order by id limit 10");
    }
    else
    {
      $result = $DBI->Query("select id, subject, ip from joinc_Trackbacks order by id limit 10");
      if (!$result)
        echo mysql_error();
    }

    $rowlist = array();
    while($row = $DBI->Fetch())
    {
      array_push($rowlist, $row);
    }
    $this->viewData[trackback] = $rowlist;
  }

  function view()
  {
    // viewData를 출력하기 위한 코드가 들어간다.
  }
}