Template 模式

来源:互联网 发布:图像压缩算法动态规划 编辑:程序博客网 时间:2024/05/20 16:07

问题

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


解决方案

Template 提供了这种情况的一个实现框架。Template 模式是采用继承的方式实现这一点: 将逻辑(算法) 框架放在抽象基类中(non-virtual function), 并定义好细节的接口(pure virtual function),子类中实现细节。

一个通用的 Template 模式的结构图为:
这里写图片描述


代码实现

#pragma once//TemplatePattern.hnamespace TemplatePattern{    class AbstractClass    {    public:        virtual ~AbstractClass();        void TemplateMethod();    protected:        virtual void PrimitiveOperation1() = 0;        virtual void PrimitiveOperation2() = 0;        AbstractClass();    private:    };    ////////////////////////////////////////////////////////////////////////////    class ConcreteClass1:public AbstractClass    {    public:        ConcreteClass1();        ~ConcreteClass1();    protected:        void PrimitiveOperation1();        void PrimitiveOperation2();    private:    };    ////////////////////////////////////////////////////////////////////////////    class ConcreteClass2:public AbstractClass    {    public:        ConcreteClass2();        ~ConcreteClass2();    protected:        void PrimitiveOperation1();        void PrimitiveOperation2();    private:    };}
//TemplatePattern.cpp#include "TemplatePattern.h"#include <iostream>using namespace std;namespace TemplatePattern{    //////////////////////////////////////////////////////////////    AbstractClass::AbstractClass()    {    }    AbstractClass::~AbstractClass()    {    }    void AbstractClass::TemplateMethod()    {        this->PrimitiveOperation1();        this->PrimitiveOperation2();    }    ///////////////////////////////////////////////////////////////////////////////    ConcreteClass1::ConcreteClass1()    {    }    ConcreteClass1::~ConcreteClass1()    {    }    void ConcreteClass1::PrimitiveOperation1()    {        cout<<"ConcreteClass1...PrimitiveOperation1"<<endl;    }    void ConcreteClass1::PrimitiveOperation2()    {        cout<<"ConcreteClass1...PrimitiveOperation2"<<endl;    }    ////////////////////////////////////////////////////////////////////////////    ConcreteClass2::ConcreteClass2()    {    }    ConcreteClass2::~ConcreteClass2()    {    }    void ConcreteClass2::PrimitiveOperation1()    {        cout<<"ConcreteClass2...PrimitiveOperation1"<<endl;    }    void ConcreteClass2::PrimitiveOperation2()    {        cout<<"ConcreteClass2...PrimitiveOperation2"<<endl;    }}
//main.cpp#include "Test.h"#include "TemplatePattern.h"int main(){    TemplatePattern::AbstractClass *p1 = new TemplatePattern::ConcreteClass1();    TemplatePattern::AbstractClass *p2 = new TemplatePattern::ConcreteClass2();    p1->TemplateMethod();    p2->TemplateMethod();    delete p1;    delete p2;    return 0;}

讨论

  Template 模式是很简单模式,但是也应用很广的模式。如上面的分析和实现中阐明的
Template 是采用继承的方式实现算法的异构,其关键点就是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。
  Template 模式获得一种反向控制结构效果, 这也是面向对象系统的分析和设计中一个原则 DIP(依赖倒置: Dependency Inversion Principles)。 其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。
  继 承 的 强 制 性 约 束 关 系 也 让 Template 模 式 有 不 足 的 地 方 , 我 们 可 以 看 到 对 于ConcreteClass 类中的实现的原语方法 Primitive1(),是不能被别的类复用。假设我们要创建一个 AbstractClass 的变体 AnotherAbstractClass,并且两者只是通用算法不一样,其原语操作想复用 AbstractClass 的子类的实现。但是这是不可能实现的,因为ConcreteClass 继承自AbstractClass,也就继承了 AbstractClass 的通用算法,AnotherAbstractClass 是复用不了ConcreteClass 的实现,因为后者不是继承自前者。
  Template 模式暴露的问题也正是继承所固有的问题,

0 0