`
runfeel
  • 浏览: 902867 次
文章分类
社区版块
存档分类
最新评论

我所理解的设计模式(C++实现)——模板方法模式(Template Method Pattern)

 
阅读更多

概述:

我们最近在开发一个支持多种压缩类型文件的解压缩且制作成pdf的一个应用。对我们的架构来说我们需要支持多种压缩文件类型,但却有固定的操作顺序(先解压缩,在读取里面的文件分析、制作pdf)。我们抽取他们的共同点:这些操作的固定顺序,把他放到我们的父类里;他们的变化点:这些个具体的操作,去留给不同的子类去实现。这个就是模板方法模式,他定义一个操作中的算法的骨架(例子中的固定的操作顺序),而将一些步骤延迟到子类中(例子中的多种压缩文件的解压缩)。

TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。是一种比较简单的设计模式,但却是代码复用的一项基本技术,在类库中尤其重要。使用的也比较普遍。

类图与实例:


这里涉及到两个角色:

抽象模版(AbstractClass角色:

定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。

定义并实现了一个模版方法。这个模版方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。这个就是定义了我们的固定的操作顺序。

具体模版(ConcreteClass角色:

实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。

每一个抽象模版角色都可以有任意多个具体模版角色与之对应,而每一个具体模版角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。就是对我们的多个压缩文件的不同的解压缩的支持。

实例:

#include <iostream>
template <typename T> class CaffeineBeverage  //咖啡因饮料
{
public:
	void PrepareRecipe() //咖啡因饮料冲泡法
	{
		BoilWater();  //把水煮沸
		Brew();    //冲泡
		PourInCup();  //把咖啡因饮料倒进杯子
		AddCondiments(); //加调料
	}
	void BoilWater()
	{std::cout << "把水煮沸" << std::endl;}
	void Brew()
	{static_cast<T *>(this)->Brew();}
	void PourInCup()
	{std::cout << "把咖啡倒进杯子" << std::endl;}
	void AddCondiments()
	{static_cast<T *>(this)->AddCondiments();}
};
class Coffee : public CaffeineBeverage<Coffee>
{
public:
	void Brew()
	{std::cout << "用沸水冲泡咖啡" << std::endl;}
	void AddCondiments()
	{std::cout << "加糖和牛奶" << std::endl;}
};
class Tea : public CaffeineBeverage<Tea>

{
public:
	void Brew()
	{std::cout << "用沸水浸泡茶叶" << std::endl;}
	void AddCondiments()
	{std::cout << "加柠檬" << std::endl;}
};
int main(void)
{
	std::cout << "冲杯咖啡:" << std::endl;
	Coffee c;
	c.PrepareRecipe();
	std::cout << std::endl;
	std::cout << "冲杯茶:" << std::endl;
	Tea t;
	t.PrepareRecipe();
	return 0;
}

适用性:

1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是OpdykeJohnson所描述过的重分解以一般化的一个很好的例子。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

3.控制子类扩展。模板方法只在特定点调用“Hook”操作,这样就只允许在这些点进行扩展。

实现要点:

1TemplateMethod模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。

2.除了可以灵活应对子步骤的变化外,不用调用我,让我来调用你的反向控制结构是TemplateMethod的典型应用。

3.在具体实现方面,被TemplateMethod调用的虚方法可以具有实现,也可以没有任何实现(抽象方法,纯虚方法),但一般推荐将它们设置为protected方法。


LCL_data原创于CSDN.NET【http://blog.csdn.net/lcl_data/article/details/9199961

其他设计模式文章请参考:我所理解的设计模式

分享到:
评论

相关推荐

    Head First 设计模式 (八) 模板方法模式(Template Method pattern) C++实现

    Head First 设计模式 (八) 模板方法模式(Template Method pattern) C++实现

    C++设计模式(Design Pattern)范例源代码

    23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm” 供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) ...

    设计模式迷你手册.chm

    设计模式迷你手册.chm,大小仅 188 KB,图文并茂,介绍性强,每个设计模式附有 C++、C# 示例源码示例。 目录: 创建型 Factory Method Abstract Factory Builder Prototype Singleton 结构型 Adapter Bridge ...

    设计模式,软件开发者必读

    2.2 FACTORY METHOD工厂方法模式 17 2.2.1 简单工厂 17 2.2.2 工厂方法 18 2.3 ABSTRACT FACTORY 抽象工厂模式 22 2.4 BUILDER PATTERN 生成器模式 25 2.5 PROTOTYPE 原型模式 28 结构型模式 30 3.1 ADAPTER 适配器...

    asp.net知识库

    动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个时间转换的问题,顺便谈谈搜索技巧 .net中的正则表达式使用高级技巧 (一) C#静态成员和...

    二十三种设计模式【PDF版】

    设计模式之 Template(模板方法) 实际上向你介绍了为什么要使用 Java 抽象类,该模式原理简单,使用很普遍. 设计模式之 Strategy(策略) 不同算法各自封装,用户端可随意挑选需要的算法. 设计模式之 Chain of ...

    java 设计模式资料

    附件中是java实现全部的设计模式,包含代码和工程(jbuilder工程),值得收藏. 此目录里包括了一书中所有23种设计模式的实现(Java 版)源码 关于代码的几点说明: 1. 代码为根据个人对Design Pattern的学习理解写...

    java 面试题 总结

    声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其...

    超级有影响力霸气的Java面试题大全文档

    exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 19、同步和异步有何异同,在什么情况下分别使用他们?举例说明。  如果数据将在线程间共享。例如正在写的数据以后可能...

Global site tag (gtag.js) - Google Analytics