定义算法的框架 - 模板方法模式

现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。

“组件协作” 模式通常包含
         1、模板方法模式
         2、观察者模式
         3、策略模式

这篇文章中我们首先来了解模板方法模式,其他两个模式在后续的文章中了解熟悉。

只要写过面向对象的程序,用过一些框架,都会使用过模板方法模式,比方QT中实现线程,那么我们一般会编写一个继承QThread的子类,然后在子类中重写run函数,这就是模板方法模式。

动机:

在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。

如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

这里重点标注了稳定变化 两个词,其实在设计模式中,中心思想大部分都是围绕这稳定与变化来展开的,对于稳定的,尽量不去更改,对于有变化需求的,尽量将这些需求与稳定的部分解耦,这就是所谓的提高代码复用与扩展。

为了更好理解上述的话,这里举个例子:请客吃饭
一般我们请客吃饭,常规步骤都是:进饭店 - 点菜 - 吃饭 - 买单 - 离开,这里稳定与变化部分便可以分为:
稳定部分进饭店买单离开整个请客步骤(框架)
变化部分点菜(不同人请不同的人吃饭,可能点的菜不一样)

如果按常规的流程处理,请员工与请老板流程可能如下:

#include 

using namespace std;

//员工餐
class Employee
{
public:
    //进饭店
    void enter()
    {
        cout << "进饭店" <

定义算法的框架 - 模板方法模式_第1张图片

从结果来看,只有点菜部分不一样,其余都一样,包括流程(框架),这种代码是没有复用性,可扩展性也很差,稳定的部分与变动的部分完全耦合到一起,假如要清客户吃饭,那么就要重新实现一遍整个流程,但是实际变化的仅仅是点菜。

为了代码复用与可扩展性,这里我们采用模板方式模式把这个请客系统中,稳定与变化的部分解耦

1、把稳定的部分(进饭店买单离开整个请客步骤(框架))封装进一个父类(Dinner)中
        2、把变化的部分(点菜)在父类中只留一个接口,具体实现放到子类(员工、老板、客户)中完成
        结构图为:
定义算法的框架 - 模板方法模式_第2张图片

#include 

using namespace std;

//父类(请客)
class Dinner
{
private:
    //进饭店
    void enter()    //稳定部分
    {
        cout << "进饭店" <dinner();

    cout << "----------请老板餐----------" << endl;
    Dinner* pB = new Boss();
    pB->dinner();
}

定义算法的框架 - 模板方法模式_第3张图片

可以看到,采用模板方式模式重构后,代码的可复用与可扩展性得到了极大提高,假如我们要请客户吃饭,那么只需要定义一个继承自Dinner类的客户子类,并在客户子类中重写order()接口函数即可,调用依旧是调用父类的run()方法。

这个例子大概描述了模板方法模式的实现方式,相信大部分人对这个很熟悉,也经常用到,只是不知道已经用了此模式。

最后再来总结下模板方法模式:

定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构,通过重定义(override 重写)该算法的某些特定步骤,达到框架与业务的解耦。

你可能感兴趣的:(设计模式(C++实现),模板方法设计模式,设计模式)