模板方法模式

设计理念

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式

为了提高代码的复用性和系统的灵活性,模板方法模式将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。

在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“请客”以及基本方法“点单”和“买单”的实现放在父类中,而对于基本方法“吃东西”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“吃面条”的实现,而另一个子类提供“吃满汉全席”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“请客”方法,提高系统的灵活性可扩展性

UML类图

模板方法模式

  • AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template
    Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
  • ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

实现代码

假如我们是一个老师,现在你要给你的学生出一份期末考试试卷。你班上有几十个学生,你将考虑如何为设计考试卷。

经分析显然学生的试卷大部分类容都是一致的,唯一不一致的是姓名和答案。老师设计好试卷,只需要把试卷交个学生填写答案即可。学生不需要把题目照抄一份。

//我们需要把试卷抽象成基类,并且给学生留下填写答案以及姓名的地方。
class TestPaper 
{ 
public: 
  void DoTestPaper(){ 
    StudentName(); 
    TestTitleOne(); 
    TestTitleTwo(); 
  }; 

  void TestTitleOne(){ 
    cout<<"题目一:X国的房价会降下来么?"<<endl; 
    AnswerOne(); 
  } 

  void TestTitleTwo(){ 
    cout<<"题目二:说说你的新闻联播的看法?"<<endl; 
    AnswerTwo(); 
  } 

  virtual void AnswerOne() = 0; 
  virtual void AnswerTwo() = 0; 
  virtual void StudentName() = 0; 
}; 

上面 AnswerOne, AnserTwo,StudentName 就是学生答题的地方,学生不需要把题目也抄下来。只需要实现我们的这三个方法就可以了。

//小红的试卷
class XiaoHongTestPaper : public TestPaper 
{ 
public: 
  void StudentName(){ 
    cout<<"姓名:小红"<<endl; 
  } 
  void AnswerOne(){ 
    cout<<"答:相信X,相信国家,明年一定降下来。"<<endl<<endl; 
  } 
  void AnswerTwo(){ 
    cout<<"答:新闻联播是我最喜欢的节目啊。"<<endl<<endl; 
  } 
}; 
//小张的试卷
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)。其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。

参考资料

《headfirst设计模式》
http://blog.youkuaiyun.com/lovelion/article/details/8299794
https://yq.aliyun.com/ziliao/126441

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值