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

模板方法模式详解
本文深入解析模板方法模式,一种常用的设计模式,用于定义算法框架,允许子类在不改变算法结构的情况下重定义某些步骤。文章详细介绍了模式的原理、适用场景及如何通过钩子操作实现子类扩展。

概述

模板方法模式(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(){}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luoyayun361

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值