Template Method Pattern

개념
- 상위 클래스에서 처리의 흐름을 정하고 하위 클래스에서 구체적인 내용을 재 정의하는 디자인 패턴 - 알고리즘의 개별 단계를 구현하는 방법을 서브클래스에서 결정한다.

I. Template Method Pattern

가. 의도

- 오퍼레이션에 알고리즘의 기본 골격 구조를 정의하고 구체적인 단계는 서브클래스에 정의한다.

- Template method 클래스의 서브클래스는 알고리즘의 구조를 변경하지 않고 알고리즘의 처리 단계를 재정의할 수 있다

 

나. 정의

- 위 클래스에서 처리의 흐름을 정하고 하위 클래스에서 구체적인 내용을 재 정의하는  디자인 패턴
- 알고리즘의 개별 단계를 구현하는 방법을 서브클래스에서 결정한다.

 

다. 활용

- 알고리즘의 변하지 않는 부분을 한 번 정의하고 다양해질 수 있는 부분을 서블클래스에서 정의할 수 있도록 구현하고자 할 때

- 서브클래스 사이의 공통적인 행위를 추출해 하나의 공통클래스로 정의할 때, 이는 일반화를 위한 refactoring의 예라 볼 수 있다. 차이를 보이는 부분을 템플릿 메소드로 정의하고, 나중에 상속받은 서브클래스가 정의하는 오퍼레이션을 호출하게 한다

- 서브클래스의 확장을 제어할 수 있다. 이는 템플릿 메소드가 어떤 특정한 시점에 hook 오퍼레이션을 호출하도록 정의하면, 실제로 이 훅 오퍼레이션이 호출되는 순간 새로운 확장이 이루어진다

 

마. 결과

- 템플릿 메소드는 코드 재사용을 위한 기본 기술이다. 템플릿 메소드는 “할리우드 제어 구조”를 만들어 내기도 하는데, 이는 “전화하지 마세요, 제가 전화할게요”이다. 이를 클래스에 적용하면, 부모 클래스는 서브클래스에 정의된 오퍼레이션을 호출할 수 있지만 반대로는 되지 않는다

 

바. 템플릿 메소드가 호출하는 오퍼레이션

- 구체적인 오퍼레이션으로 ConcreteClass나 클라이언트 클래스에 정의된 오퍼레이션

- AbstractClass에 정의된 오퍼레이션 중 구체적인 알고리즘을 가지고 있는 오퍼레이션

- 팩토리 메소드

- 훅 오퍼레이션은 기본 행위를 제공하고, 필요하다면 서브클래스에서 확장 가능한 행위를 제공하는 오퍼레이션이다. 일반적으로 아무런 내용도 정의하고 있지 않다

 

사. 관련 패턴

- Factory Method 패턴은 Template Method 패턴이다.  Template Method 패턴은 상속을 이용해 다양한 알고리즘을 만들어 내는데 이런 점에서 Strategy 패턴과도 관계가 있다

- AbstractClass: 서브클래스들이 반드시 구현해야 하는 알고리즘 처리 단계 내의 기본 오퍼레이션이 무엇인지를 정의한다. 서브클래스에서 이들 오퍼레이션들을 구현한다. 이 클래스에서 템플릿 메소드를 구현하는데, 그 방법은 알고리즘의 기본 골격 구조를 정의하여 템플릿 메소드가 다른 객체에 의해 정의된 오퍼레이션뿐만 아니라 인터페이스로 정의된 기본 오퍼레이션을 재정의한 서브클래스에게 메시지가 전달되어 기본 골격 구조를 준수하되 다른 결과가 나타나게 된다.

- ConcreateClass: 서브클래스마다 기본 오퍼레이션을 다르게 구현한다.

 

아. 소스코드

 

#include <string>

#include <iostream>

 

class HelloWorld {

public:

virtual ~HelloWorld() { }

void output() {

write_string("Hello world!");

write_endl();

};

virtual void write_string(const std::string &)=0;

virtual void write_endl()=0;

};

 

class HelloWorldImpl : public HelloWorld {

public:

void write_string(const std::string & str) {

std::cout << str;

}

void write_endl() {

 std::cout << std::endl;

}

};

 

void hello_world(HelloWorld & hw) {

hw.output();

}

 

int main() {

HelloWorldImpl hw;

hello_world(hw);

return 0;

}

댓글