Template模式

Template模式

在面向对象系统的分析与设计过程中经常会遇到这样一种情况:对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现,但是逻辑(算法)的框架(或通用的应用算法)是相同的。Template提供了这种情况的一个实现框架。

Template模式是采用继承的方式实现这一点:将逻辑(算法)框架放在抽象基类中,并定义好细节的接口,子类中实现细节。

结构图

template method

举例

结构化软件开发设计流程(template1):App调用Lib

  • Library开发:

  1. 开发1、3、5三个步骤
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //库开发
    class Library {
    public:
    void Step1() {
    //...
    }

    void Step3() {
    //...
    }

    void Step5() {
    //...
    }
    };
  • Application开发:

  1. 开发2、4两个步骤;
  2. 程序主流程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    //应用开发
    class Application {
    public:
    bool Step2() {
    //...
    }

    void Step4() {
    //...
    }
    };

    int main()
    {
    Library lib();
    Application app();

    lib.Step1();

    if (app.Step2()) {
    lib.Step3();
    }

    for (int i = 0; i < 4; i++) {
    app.Step4();
    }

    lib.Step5();
    }

面向对象软设计流程(template2):Lib调用App

  • Library开发:

  1. 开发1、3、5三个步骤
  2. 程序主流程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    //库开发
    class Library {
    public:
    //稳定 template method
    void Run() {

    Step1();

    if (Step2()) { //支持变化 ==> 虚函数的多态调用
    Step3();
    }

    for (int i = 0; i < 4; i++) {
    Step4(); //支持变化 ==> 虚函数的多态调用
    }

    Step5();
    }

    virtual ~Library() { }

    protected:

    void Step1() {//稳定
    //...
    }

    void Step3() {//稳定
    //...
    }

    void Step5() {//稳定
    //...
    }

    virtual bool Step2() = 0;//变化
    virtual bool Step4() = 0;//变化
    };
  • Application开发:

  1. 开发2、4两个步骤
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //应用开发
    class Application : public Library{
    protected:
    virtual bool Step2(){
    //...子类重写实现
    }

    virtual bool Step4(){
    //...子类重写实现
    }
    };

    int main()
    {
    Library* pLib = new Application();//多态指针
    lib->Run();

    delete pLib;
    }

相关代码:

在基类Analyse.h中只声明纯虚函数:

1
virtual int Analyse(const char* data, uint32_t dataSize) = 0;

Analyse.cpp中Recv用于接收数据,并进行后续分析处理,但Analyse由子类自己实现:

1
2
3
4
5
6
7
8
9
10
11
12
int Analyse::Recv(const char* data, uint32_t dataSize)
{
if (m_data.IsIgnoreLink())
{
return 0;
}

//...

int rc = Analyse(data, dataSize);
return rc;
}

比如SubAnlyse中在子类中就编程了虚函数,子类的子类即孙子类可以覆盖该虚函数。