본문 바로가기
카테고리 없음

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

by 까망 하르방 2022. 8. 30.
반응형

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

상위 클래스에서 먼저 전체 흐름(큰 골격)을 구현하고,

실제적인 동작은 하위 클래스에서 구현

이러한 동작은 후크 기능과 유사하다.

후크 (Hook)

하위 클래스에서 구현되는 함수를 "후크 메서드"라고도 한다.
"후크"는 중복된 코드를 제거하고
처리 로직의 일부를 변경할 때 자주 사용하는 기법

 

 

📌 디자인 패턴(Design Pattern)이란?

 

💻 디자인 패턴(Design Pattern)이란?

👨‍💻 디자인 패턴(Design Pattern)이란? • SW 개발 방법 중에서도 구조적인 문제 해결에 목적을 둔다. • 알고리즘과 같이 특정 문제를 해결하는 Logic 형태보다는    특정 상황에 적용할 수 있

zoosso.tistory.com


 

예제 코드

#include <iostream>

using namespace std;

class Parent
{
protected:
    virtual void preCondition() { return; };
    virtual bool postCondition() { return true; }
public:
    void doSth()
    {
        preCondition();
        cout << "do Sth..." << endl;
        postCondition();
    }
};

// --------------------------

class Child_A : public Parent
{
protected:
    void preCondition() override
    {
        cout << "Pre... A" << endl;
    }
    bool postCondition() override
    {
        cout << "Post... A" << endl;
        return true;
    }
};

// --------------------------

class Child_B : public Parent
{
protected:
    void preCondition() override
    {
        cout << "Pre... B" << endl;
    }
    bool postCondition() override
    {
        cout << "Post... B" << endl;
        return true;
    }
};

// --------------------------

int main()
{
    Child_B p;
    p.doSth();
}

템플릿 메서드 코드 결과

 

상위 클래스에서 정의하는 부분 = 템플릿 메서드

하위 클래스마다 다르게 작성된 부분 = 후크

서브 클래스에서는 단순하게 처리해서 개입 여부를 정할 수도 있다.

 

템플릿패턴은 알고리즘의 구조는 변경하지 않고

알고리즘의 각 단계를 서브클래스에서 재정의한다.

공통된 메서드를 노출함으로써 처리 로직에 집중한다.

→ 중복 코드 제거에 흔히 사용


 

멀티스레드 환경으로 예시를 들어보자.

상황을 억지로 만드는 듯하지만 😅

 

멀티스레드 환경에서는 Dead Lock에 빠지지 않기 위해

작업 전/후로 Lock/Unlock 방식이 존재한다.

▶ Lock  {동작}  Unlock

 

 

예제 코드

#include <iostream>
#include <vector>

using namespace std;

class Parent
{

protected:
    virtual void ParentImp() // 재정의 되어야 하는 함수
    {
        cout << "Parent" << endl;
    }
public:
    void Draw()
    {
        cout << "mutex lock" << endl;
        ParentImp();
        cout << "mutex unlock" << endl;
    }
};

// ----------------------------------------

class Child_R : public Parent
{
public:
    void ParentImp() override { cout << "R..." << endl; }
};


class Child_C : public Parent
{
public:
    void ParentImp() override { cout << "C..." << endl; }
};


class Child_T : public Parent
{
public:
    void ParentImp() override { cout << "T..." << endl; }
};

// ----------------------------------------

int main()
{
    vector<Parent*> v;
    int cmd;


    while (1)
    {
        cin >> cmd;
        if (cmd == 1) v.push_back(new Child_R);
        else if (cmd == 2) v.push_back(new Child_C);
        else if (cmd == 3) v.push_back(new Child_T);
        else if (cmd == 4)
        {
            for (auto p : v) p->Draw();
        }
        
    }
}

코드 결과

 

{동작}은 파생클래스마다 변경될 수 있지만

전체적인 lock, unlock 순서는 변하지 않는다.


 

정리

공통부와 가변부의 분리

변하는 부분을 분리하여 전체적인 흐름은 변하지 않도록 해야 한다.

→ C++ 에서는 변하는 부분을 찾아 가상함수로 분리할 수 있다.

 

템플릿 메서드 패턴은 공통적인 프로세스를 묶어 처리하는 패턴

유사한 동작을 할 때 템플릿 메서드 패턴 적용을 고려해보자.

 

전략 패턴 비교

전략 패턴과 같이 "알고리즘 변형" 하는 것에서 유사하다.

• 템플릿 메서드가 골격을 제공하고 (일부) 내용만 변형 (상속)

• 전략 패턴은 알고리즘 전체를 교체할 수 있다. (위임)

반응형

댓글