您的位置:首页 > 其它

Template模式详解--设计模式(13)

2016-06-30 08:57 176 查看
Template模式来源:

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

Template模式作用:

Template模式又叫模板方法模式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情冴下,重新定义算法中的某些步骤。
我们使用冲泡咖啡和冲泡茶的例子
加工流程:
咖啡冲泡法:1.把水煮沸、2.用沸水冲泡咖啡、3.把咖啡倒进杯子、4.加糖和牛奶
茶冲泡法: 1.把水煮沸、2.用沸水冲泡茶叶、3.把
茶倒进杯子、4.加蜂蜜
Template模式UML结构图如图1所示:

[b]


[/b]

[b]Template模式的构成:

[/b]

抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。

具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。

Template模式的代码示例:

TemplateMethod.h

#ifndef _TEMPLATEMETHOD_H_
#define _TEMPLATEMETHOD_H_

//抽象模板,并定义了一个模板方法。
class AbstractClass
{
public:
~AbstractClass();
//具体的模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,它们都推迟到子类中实现
void TemplateMethod();
//一些抽象行为,放到子类中去实现
virtual void PrimitiveOperation1()=0;
virtual void PrimitiveOperation2()=0;
protected:
AbstractClass();
private:
};

//实现基类所定义的抽象方法
class ConcreteClassA : public AbstractClass
{
public:
ConcreteClassA();
~ConcreteClassA();
//实现基类定义的抽象行为
virtual void PrimitiveOperation1();
virtual void PrimitiveOperation2();
private:
};

//实现基类所定义的抽象方法
class ConcreteClassB : public AbstractClass
{
public:
ConcreteClassB();
~ConcreteClassB();
//实现基类定义的抽象行为
virtual void PrimitiveOperation1();
virtual void PrimitiveOperation2();
private:
};
#endif
TemplateMethod.cpp

#include "TemplateMethod.h"
#include <iostream>

using namespace std;

AbstractClass::AbstractClass()
{}

AbstractClass::~AbstractClass()
{}

void AbstractClass::TemplateMethod()
{
this->PrimitiveOperation1();
this->PrimitiveOperation2();
}

ConcreteClassA::ConcreteClassA()
{}

ConcreteClassA::~ConcreteClassA()
{}

void ConcreteClassA::PrimitiveOperation1()
{
cout << "ConcreteClassA::PrimitiveOperation1" << endl;
}

void ConcreteClassA::PrimitiveOperation2()
{
cout << "ConcreteClassA::PrimitiveOperation2" << endl;
}

ConcreteClassB::ConcreteClassB()
{}

ConcreteClassB::~ConcreteClassB()
{}

void ConcreteClassB::PrimitiveOperation1()
{
cout << "ConcreteClassB::PrimitiveOperation1" << endl;
}

void ConcreteClassB::PrimitiveOperation2()
{
cout << "ConcreteClassB::PrimitiveOperation2" << endl;
}
Main.cpp

#include "TemplateMethod.h"

int main()
{
//ConcreteClassA与ConcreteClassB可相互替换
AbstractClass* pAbstract = new ConcreteClassA();
pAbstract->TemplateMethod();

pAbstract = new ConcreteClassB();
pAbstract->TemplateMethod();

return 0;
}


Template模式使用场景:

(1).在某些类的算法中,用了相同的方法,造成代码的重复。

(2).控制子类扩展,子类必须遵守算法规则。
Template模式优点:

(1).模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。

(2).子类实现算法的某些细节,有助于算法的扩展。

(3).通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

Template模式缺点:

(1).每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。

Template模式使用总结:

Template模式是很简单模式,但是也应用很广的模式。如上面的分析和实现中阐明的Template是采用继承的方式实现算法的异构,其关键点就是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。

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

Template模式暴露的问题也正是继承所固有的问题,Strategy模式则通过组合(委托)来达到和Template模式类似的效果,其代价就是空间和时间上的代价。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: