详解设计模式中的模板方法模式及在C++中的使用

2020-01-06 14:38:40王振洲

小张的试卷:


class XiaoZhangTestPaper : public TestPaper 
{ 
public: 
  void StudentName(){ 
    cout<<"姓名:小张"<<endl; 
  } 
  void AnswerOne(){ 
    cout<<"答:呵呵,还是去做你的X国梦吧。"<<endl<<endl; 
  } 
  void AnswerTwo(){ 
    cout<<"答:我很幸福"<<endl<<endl; 
  } 
}; 

客户端:


int main(int argc, char* argv[]) 
{ 
  XiaoHongTestPaper paper1; 
  paper1.DoTestPaper(); 
 
  XiaoZhangTestPaper paper2; 
  paper2.DoTestPaper(); 
 
  system("pause"); 
  return 0; 
} 


关于模板方法的讨论

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

模板方法模式获得一种反向控制结构效果,这也是面向对象系统的分析和设计中一个原则 DIP(依赖倒置:Dependency Inversion Principles)。其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。

继 承 的 强 制 性 约 束 关 系 也 让模板方法模 式 有 不 足 的 地 方 , 我 们 可 以 看 到 对 于ConcreteClass 类中的实现的原语方法 Primitive1(),是不能被别的类复用。假设我们要创建一个 AbstractClass 的变体 AnotherAbstractClass,并且两者只是通用算法不一样,其原语操作想复用 AbstractClass 的子类的实现。但是这是不可能实现的,因为 ConcreteClass 继承自AbstractClass,也就继承了 AbstractClass 的通用算法,AnotherAbstractClass 是复用不了ConcreteClass 的实现,因为后者不是继承自前者。

模板方法模式暴露的问题也正是继承所固有的问题,策略模式则通过组合(委托)来达到和模板方法模式类似的效果,其代价就是空间和时间上的代价,关于策略模式的详细讨论请参考 Strategy 模式解析。



注:相关教程知识阅读请移步到C++教程频道。