C++设计模式--模板方法模式

版权声明:支持原创,转载请说明~ https://blog.csdn.net/luoyayun361/article/details/88326650

概述

模板方法模式(Template Method)是定义一个操作中的算法框架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法框架的结构即可重定义该算法的某些特定步骤。

模板方法模式的一个重要特征是它的定义在基类中(有时作为一个私有成员函数)并且不能改动—模板方法木事就是“坚持相同的代码”。它调用其他基类函数(就是那些被覆盖的虚函数)以便完成其工作,但是其他人不必直接调用这些虚函数。

模板方法的适用性

模板方法应用于一下几种情况:

  • 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
  • 各个子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
  • 控制子类扩展。

示例

#include <iostream>

using namespace std;

class ApplicationFramework
{
public:
    void templateMethod(){
        for(int i = 0 ; i < 5 ; ++i){
            customize1();
            customize2();
        }
    }
    virtual ~ApplicationFramework();

protected:
    virtual void customize1() = 0;
    virtual void customize2() = 0;

};

class myApp : public ApplicationFramework
{
public:
    ~myApp();
protected:
    void customize1(){cout << "hello ";}
    void customize2(){cout << "world~" << endl;}
};

int main()
{
    myApp app;
    app.templateMethod();
    return 0;
}

ApplicationFramework::~ApplicationFramework(){}
myApp::~myApp(){}

以上示例可以看到,在基类中的函数templateMethod就是一个模板方法,改方法中调用了两个虚函数,而在子类中对虚函数进行实现,在子类实例化后调用templateMethod 时,会自动调用子类中的虚函数实现。

钩子操作

模板方法模式中的钩子操作,它提供了缺省的行为,子类可以在必要时进行扩展,一个钩子操作在缺省操作的通常是一个空操作。

上面这段话可能不太好理解,简单来说,所谓的钩子操作就是在基类中定义一个虚函数(注意,不是纯虚函数)并且该虚函数有简单的实现(也可以是空操作),那么子类在必要的时候可以重新定义并实现该虚函数然后做自己的操作。这样便于在子类中进行扩展。这样一来,在模板方法中就可以通过钩子操作来知道子类中某些真正的行为。

很重要的一点是,模板方法应该指明哪些 操作是钩子操作(可以被重定义),哪些是抽象操作(必须被重定义),要有效的重用一个抽象类,子类编写者必须明确了解哪些操作是设计为有待重定义的。

将上面的示例修改一下:

#include <iostream>

using namespace std;

class ApplicationFramework
{
public:
    void templateMethod(){
        for(int i = 0 ; i < 5 ; ++i){
            customize1();
            customize2();
        }
        if(hookOperation()){
            cout << "hello everyone!";
        }
    }
    virtual ~ApplicationFramework();

protected:
    virtual void customize1() = 0;
    virtual void customize2() = 0;
    //钩子操作
    virtual bool hookOperation(){return  false;}

};

class myApp : public ApplicationFramework
{
public:
    ~myApp();
protected:
    void customize1(){cout << "hello ";}
    void customize2(){cout << "world~" << endl;}
    //钩子操作实现
    bool hookOperation(){return  true;}
};

int main()
{
    myApp app;
    app.templateMethod();
    return 0;
}

ApplicationFramework::~ApplicationFramework(){}
myApp::~myApp(){}

对于有多个子类实现时,钩子操作就可以便于子类中的扩展啦。

猜你喜欢

转载自blog.csdn.net/luoyayun361/article/details/88326650