Thinking Different







Template Method Pattern - 템플릿 메서드 패턴


  • 상위 클래스에서 처리의 흐름을 제어하며, 하위클래스에서 처리의 내용을 구체화한다.
  • 여러 클래스에 공통되는 사항은 상위 추상 클래스에서 구현하고, 각각의 상세부분은 하위 클래스에서 구현한다.
  • 코드의 중복을 줄이고, Refactoring에 유리한 패턴으로 상속을 통한 확장 개발 방법으로써 전략 패턴(Strategy Pattern)과 함께 가장 많이 사용되는 패턴중에 하나이다.



[고려사항]

1. 멤버 함수들의 접근 범위 지정에 대한 명확화가 필요

2. 가상함수, 일반함수로 선언에 대한 결정이 필요

3. 재정의 함수(virtual)의 수를 줄이는 것이 필요(virtual table 확장에 따른 perfomance 문제점 발생)






샘플 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "stdafx.h"
 
class AbstractClass
{
private:
    virtual void subMethod() = 0;
 
public:
    void templateMethod() { subMethod(); }
};
 
class ConcreteClass : public AbstractClass
{
public:
    void subMethod() override { cout << "subMethod" << endl; }
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    AbstractClass *test = new ConcreteClass;
 
    test->templateMethod();
 
    delete test;
 
    return 0;
}




예제를 통한 템플릿 메서드 패턴(Template Method Pattern) 알아보기




음료를 만든다고 가정했을때, 각각의 커피와 홍차는 음료로부터 중복되는 코드가 발생하는데, 여기서 중복되는 코드를 상위 음료 클래스에서 구현하고 각각의 세부적인 부분들은 하위 클래스에서 구현한다.




이렇게 하위클래스에 필요한 것들만 구현하고 나머지 중복 코드는 상위에서 구현한다.



음료 클래스 다이어그램




최종 예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "stdafx.h"
 
//------------------------------------------------------------------
// 음료 (추상) 클래스
class 음료
{
private:
    virtual void 만들기() = 0;
    virtual void 첨가물추가() = 0;
    
    void 물끓이기() { cout << "물을 끓인다" << endl; }
    void 컵에담기() { cout << "컵에 따른다" << endl; }
 
public:
    void 처리() 
    {
        물끓이기();
        첨가물추가();
        만들기();
        컵에담기();
    }
};
 
//------------------------------------------------------------------
// 커피 (하위) 클래스
class 커피 : public 음료
{
private:
    void 만들기() override { cout << "커피를 만든다" << endl; }
    void 첨가물추가() override { cout << "설탕 프림을 넣는다" << endl; }
};
 
//------------------------------------------------------------------
// 홍차 (하위) 클래스
class 홍차 : public 음료
{
private:
    void 만들기() override { cout << "홍차를 만든다" << endl; }
    void 첨가물추가() override { cout << "레몬을 넣는다" << endl; }
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    음료* coffee = new 커피;
    음료* tea = new 홍차;
 
    coffee->처리();
    tea->처리();
 
    delete coffee;
    delete tea;
 
    return 0;
}