템플릿 메소드 (template method)

2024. 7. 13. 09:46소프트웨어/디자인 패턴

[wikipidia] template method UML 이미지

구조를 변경하지 않고 알고리즘의 특정 단계들을 다시 정의해서 사용할 수 있게 해준다.

즉, 구현되어 있는데 알고리즘이 실행과정은 유지한 채로 알고리즘에서 각 단계의 실제 처리를 서브클래스 에서 동작을 재정의 할 수 있다.

 

<예시1 - ChatGPT 생성>

#include <iostream>

// Abstract class
class AbstractClass {
public:
    // Template method
    void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
        concreteOperation();
    }

    // Abstract operations to be implemented by subclasses
    virtual void primitiveOperation1() = 0;
    virtual void primitiveOperation2() = 0;

    // Concrete operation with default implementation
    void concreteOperation() {
        std::cout << "AbstractClass: concreteOperation" << std::endl;
    }

    // Virtual destructor to allow proper cleanup of derived classes
    virtual ~AbstractClass() {}
};

// Concrete class A
class ConcreteClassA : public AbstractClass {
public:
    void primitiveOperation1() override {
        std::cout << "ConcreteClassA: primitiveOperation1" << std::endl;
    }

    void primitiveOperation2() override {
        std::cout << "ConcreteClassA: primitiveOperation2" << std::endl;
    }
};

// Concrete class B
class ConcreteClassB : public AbstractClass {
public:
    void primitiveOperation1() override {
        std::cout << "ConcreteClassB: primitiveOperation1" << std::endl;
    }

    void primitiveOperation2() override {
        std::cout << "ConcreteClassB: primitiveOperation2" << std::endl;
    }
};

// Main function to demonstrate the Template Method pattern
int main() {
    AbstractClass* classA = new ConcreteClassA();
    AbstractClass* classB = new ConcreteClassB();

    std::cout << "ClassA's Template Method Execution:" << std::endl;
    classA->templateMethod();

    std::cout << "\nClassB's Template Method Execution:" << std::endl;
    classB->templateMethod();

    delete classA;
    delete classB;

    return 0;
}

AbstractClass* class = [new ConcreateClassA()] or [new ConcreateClassB()]

 

객체 생성단계에서 어떤 것을 생성하던 인터 페이스 역할을 하는 AbstractClass의 templateMethod를 호출한다면 생성된 객체의 templateMethod가 호출 될 것이다. 상속받은 class에서 해당 메소드를 구현하도록 함.

 

 

좀 더 쉬운 예시를 들어보면 동물 클래스를 만들고 개와 고양이 클래스가 이를 상속받아 각각 울음소리를 구현한다면, 사용자가 개를 선택한다면 개의 울음소리가 고양이를 선택한다면 고양이 울음소리가 재생 될 것이다. 아래 예시 참고.

 

<예시2 - ChatGPT 생성>


#include <iostream>  

// Abstract class representing Animal  
class Animal {  
public:  
    // Template method  
    void cry() {  
        makeSound();  
        breathe();  
    }  

    // Abstract operation to be implemented by subclasses  
    virtual void makeSound() = 0;  

    // Concrete operation with default implementation  
    void breathe() {  
        std::cout << "Animal: breathing" << std::endl;  
    }  

    // Virtual destructor to allow proper cleanup of derived classes  
    virtual ~Animal() {}  
};  

// Concrete class representing Dog  
class Dog : public Animal {  
public:  
    void makeSound() override {  
        std::cout << "Dog: Woof Woof" << std::endl;  
    }  
};  

// Concrete class representing Cat  
class Cat : public Animal {  
public:  
    void makeSound() override {  
        std::cout << "Cat: Meow Meow" << std::endl;  
    }  
};  

// Main function to demonstrate the Template Method pattern  
int main() {  
    Animal\* dog = new Dog();  
    Animal\* cat = new Cat();  

    std::cout << "Dog's cry method execution:" << std::endl;  
    dog->cry();  

    std::cout << "\\nCat's cry method execution:" << std::endl;  
    cat->cry();  

    delete dog;  
    delete cat;  

    return 0;  
}

 

참조: https://ko.wikipedia.org/wiki/%ED%85%9C%ED%94%8C%EB%A6%BF_%EB%A9%94%EC%86%8C%EB%93%9C_%ED%8C%A8%ED%84%B4