C++设计模式编程中Template Method模板方法模式的运用

 更新时间:2016年03月09日 14:34:37   作者:梦在天涯  
这篇文章主要介绍了C++设计模式编程中Template Method模板方法模式的运用,讲到了包括模板方法模式中的细分方法以及适用场景,需要的朋友可以参考下

准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模版方法模式的用意。

很多人可能没有想到,模版方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模版方法模式而没有意识到自己已经使用了这个模式。模版方法模式是基于继承的代码复用的基本技术,模版方法模式的结构和用法也是面向对象设计的核心。

模版方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本法方法总汇起来的方法叫做模版方法(template method),这个设计模式的名字就是从此而来。

模版方法模式中的方法

模版方法中的方法可以分为两大类:模版方法(Template Method)和基本方法(Primitive Method)。

模版方法

一个模版方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模版方法一般会在抽象类中定义,并由子类不加以修改地完全继承下来。

基本方法

基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。

  • 抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在C#语言里一个抽象方法以abstract关键字标示出来。
  • 具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。在C#语言里面,一个具体方法没有abstract关键字。
  • 钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。(Visual FoxPro中项目向导建立的项目会使用一个AppHook类实现监视项目成员变化,调整系统结构的工作。)钩子方法的名字通常以do开始。


模板方法模式的实现

完整代码示例(code):模板方法模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 VC 6.0 下测试运行)。

代码片断 1:Template.h

//Template.h
#ifndef _TEMPLATE_H_
#define _TEMPLATE_H_
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:
};
#endif //~_TEMPLATE_H_

代码片断 2:Template.cpp

#include "Template.h"
#include <iostream>
using namespace std;
AbstractClass::AbstractClass(){
}
AbstractClass::~AbstractClass(){
}
void AbstractClass::TemplateMethod(){
   this->PrimitiveOperation1();
  this->PrimitiveOperation2();
}
ConcreteClass1::ConcreteClass1(){
}
ConcreteClass1::~ConcreteClass1(){
}
void ConcreteClass1::PrimitiveOperation1(){
  cout<<"ConcreteClass1...PrimitiveOperat
  ion1"<<endl;
}
void ConcreteClass1::PrimitiveOperation2(){
  cout<<"ConcreteClass1...PrimitiveOperat
  ion2"<<endl;
}
ConcreteClass2::ConcreteClass2(){
}
ConcreteClass2::~ConcreteClass2(){
}
void ConcreteClass2::PrimitiveOperation1(){
cout<<"ConcreteClass2...PrimitiveOperat
ion1"<<endl;
}
void ConcreteClass2::PrimitiveOperation2(){
  cout<<"ConcreteClass2...PrimitiveOperat
  ion2"<<endl;
}

代码片断 3:main.cpp

#include "Template.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[]){
  AbstractClass* p1 = new ConcreteClass1();
  AbstractClass* p2 = new ConcreteClass2();
  p1->TemplateMethod();
  p2->TemplateMethod();
  return 0;
}

代码说明:由于模板方法模式的实现代码很简单,因此解释是多余的。其关键是将通用算法(逻辑)封装起来,而将算法细节让子类实现(多态)。

唯一注意的是我们将原语操作(细节算法)定义未保护(Protected)成员,只供模板方法调用(子类可以)。


适用场景
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是O p d y k e 和J o h n s o n 所描述过的“重分解以一般化”的一个很好的例子[ O J 9 3 ]。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
控制子类扩展。模板方法只在特定点调用“h o o k ”操作(参见效果一节),这样就只允许在这些点进行扩展。

相关文章

  • C语言 深入理解动态规划之计数类DP

    C语言 深入理解动态规划之计数类DP

    动态规划可谓是大名鼎鼎,笔试面试中的高频考点,也是重点难点,动态规划类型题目灵活多变,难度系数也相对较高,往往我们做不好动态规划的题目就会与心仪的offer失之交臂,本篇文章我们就一起来研究一下动态规划的计数类DP
    2022-04-04
  • c++智能指针unique_ptr的使用

    c++智能指针unique_ptr的使用

    本文主要介绍了c++智能指针unique_ptr的使用,与shared_ptr作用类似,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • 基于Matlab图像处理的公路裂缝检测实现

    基于Matlab图像处理的公路裂缝检测实现

    随着公路的大量投运,公路日常养护和管理已经成为制约公路运营水平提高的瓶颈,特别是路面状态采集、检测维护等工作更是对传统的公路运维模式提出了挑战。这篇文章主要介绍了如何通过Matlab图像处理实现公路裂缝检测,感兴趣的可以了解一下
    2022-02-02
  • 深入理解C++中的vector类的用法及特性

    深入理解C++中的vector类的用法及特性

    vector直接翻译过来为向量,在C++中为封装动态数组的容器,且有序,需要的朋友可以参考下
    2016-05-05
  • C++中的数据内存分布原理

    C++中的数据内存分布原理

    这篇文章主要介绍了C++中的数据内存分布,主要从动态内存管理方式,内存泄漏等方面介绍的,文中也有相关的示例代码,需要的朋友可以参考下
    2023-05-05
  • c++11中关于std::thread的join的详解

    c++11中关于std::thread的join的详解

    这篇文章主要介绍了c++11中关于std::thread的join详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • opencv3/C++基于颜色的目标跟踪方式

    opencv3/C++基于颜色的目标跟踪方式

    今天小编就为大家分享一篇opencv3/C++基于颜色的目标跟踪方式,具有很好的参考价值,希望对的有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • C/C++详解如何实现文件备份

    C/C++详解如何实现文件备份

    这篇文章主要介绍了C/C++详解如何实现文件备份,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • C++中套接字库sockpp的使用详解

    C++中套接字库sockpp的使用详解

    sockpp是一个开源、简单、现代的C++套接字库,这篇文章主要为大家详细介绍一下套接字库sockpp的使用,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2023-11-11
  • 浅谈C++内存分配及变长数组的动态分配

    浅谈C++内存分配及变长数组的动态分配

    下面小编就为大家带来一篇浅谈C++内存分配及变长数组的动态分配。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09

最新评论