Template模板方法模式
作用:定义一个操作中的算法的骨架。而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
其关键是将通用算法(逻辑)封装在抽象基类中,并将不同的算法细节放到子类中实现。
UML图如下:
AbstractClass是抽象类,其实也就是一个抽象模板,定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶层逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到之类实现。顶层逻辑也有可能调用一些具体方法。
ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
特点:
模板方法模式是通过把不变行为搬移到基类,去除之类中的重复代码来体现它的优势。
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。
代码如下:
TemplateMethod.h
1 #ifndef _TEMPLATEMETHOD_H_ 2 #define _TEMPLATEMETHOD_H_ 3 4 //抽象模板,并定义了一个模板方法。 5 class AbstractClass 6 { 7 public: 8 ~AbstractClass(); 9 //具体的模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,它们都推迟到子类中实现 10 void TemplateMethod(); 11 //一些抽象行为,放到子类中去实现 12 virtual void PrimitiveOperation1()=0; 13 virtual void PrimitiveOperation2()=0; 14 protected: 15 AbstractClass(); 16 private: 17 }; 18 19 //实现基类所定义的抽象方法 20 class ConcreteClassA : public AbstractClass 21 { 22 public: 23 ConcreteClassA(); 24 ~ConcreteClassA(); 25 //实现基类定义的抽象行为 26 virtual void PrimitiveOperation1(); 27 virtual void PrimitiveOperation2(); 28 private: 29 }; 30 31 //实现基类所定义的抽象方法 32 class ConcreteClassB : public AbstractClass 33 { 34 public: 35 ConcreteClassB(); 36 ~ConcreteClassB(); 37 //实现基类定义的抽象行为 38 virtual void PrimitiveOperation1(); 39 virtual void PrimitiveOperation2(); 40 private: 41 }; 42 #endif
TemplateMethod.cpp
1 #include "TemplateMethod.h" 2 #include <iostream> 3 4 using namespace std; 5 6 AbstractClass::AbstractClass() 7 {} 8 9 AbstractClass::~AbstractClass() 10 {} 11 12 void AbstractClass::TemplateMethod() 13 { 14 this->PrimitiveOperation1(); 15 this->PrimitiveOperation2(); 16 } 17 18 ConcreteClassA::ConcreteClassA() 19 {} 20 21 ConcreteClassA::~ConcreteClassA() 22 {} 23 24 void ConcreteClassA::PrimitiveOperation1() 25 { 26 cout << "ConcreteClassA::PrimitiveOperation1" << endl; 27 } 28 29 void ConcreteClassA::PrimitiveOperation2() 30 { 31 cout << "ConcreteClassA::PrimitiveOperation2" << endl; 32 } 33 34 ConcreteClassB::ConcreteClassB() 35 {} 36 37 ConcreteClassB::~ConcreteClassB() 38 {} 39 40 void ConcreteClassB::PrimitiveOperation1() 41 { 42 cout << "ConcreteClassB::PrimitiveOperation1" << endl; 43 } 44 45 void ConcreteClassB::PrimitiveOperation2() 46 { 47 cout << "ConcreteClassB::PrimitiveOperation2" << endl; 48 }
Main.cpp
1 #include "TemplateMethod.h" 2 3 int main() 4 { 5 //ConcreteClassA与ConcreteClassB可相互替换 6 AbstractClass* pAbstract = new ConcreteClassA(); 7 pAbstract->TemplateMethod(); 8 9 pAbstract = new ConcreteClassB(); 10 pAbstract->TemplateMethod(); 11 12 return 0; 13 }