Chinaunix首页 | 论坛 | 博客
  • 博客访问: 539165
  • 博文数量: 252
  • 博客积分: 6057
  • 博客等级: 准将
  • 技术积分: 1635
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-21 10:17
文章分类

全部博文(252)

文章存档

2013年(1)

2012年(1)

2011年(32)

2010年(212)

2009年(6)

分类: C/C++

2010-03-22 12:47:35

模板方法(Template Method)模式(1)

模板方法模式是一个相当简单,但使用非常广泛的设计模式。

顾名思义,模板是一个可以产生多个具有同样形状物体的模子。例如,砖场的砖坯模子,食品厂的月饼模子等。在这里,模板是可以产生多个具有相同骨架的 算法模子。

什么是算法骨架?如果一个算法是通过一系列方法调用完成的,那么由这些方法组成的固定调用序列就称为算法骨架。例如,某一个算法中有3个方法调用:

Method1();
Method2();
Method3();

如果这个调用序列中各个方法的顺序是固定的,那么就可以把它们封装到一个方法中,例如:

void tmpMethod(){
Method1();
Method2();
Method3();
}

那么tmpMethod()就是算法骨架。之所以称为骨架,是因为它只表示了一种固定的结构,对其中各个方法的具体实现并没有进行任何约束,所以这 个骨架也可以看做一个算法模板。又因为这个模板是以方法方式提供的,所以tmpMethod()也就被称为模板方法。这很像某些学校对教师上课的要求:复 习上次课重点→引入新课→讲解新课→提问→答疑→小结→提出下次课预习内容→留作业→下课。这个骨架(格式)是不变的,而实际课程内容则是可变的。

考虑到算法通常需要一些基本数据,因此用抽象类来定义模板是再合适不过了。模板方法模式的简略类图如图4-8所示。

 
图4-8  模板方法
模式的简略类图

具体做法为:

1)在抽象类中封装模板方法。

2)根据具体需要,把模板方法中需要调用的具体方法定义成子类必须实现的抽象方法。

例如,在某个算法中要用到如下两个方法:void hookMethod()和void abstractMethod()。如果业务逻辑要求这两个方法的调用顺序固定为:

hookMethod();
abstractMethod();
那 么就可以用一个方法来封装它们,即:
void templetMethod(){
hookMethod();
abstractMethod();
}
显 然,方法templetMethod()就是业务逻辑所要求的算法骨架。这样,按上述思想定义的抽象类AbstractClass就是如图4-9所示的样 子。
 
(点击查看大图)图4-9  模板方法模式的典型类图



其中那个固定了算法骨架的templetMethod()方法就是模板方法,而抽象方法则由子类ConcreteClass(具体类)根据具体业务 逻辑来实现。由于客户面对的是抽象类,所以抽象方法实现的任何变化都不会影响到客户端,从而在一定程度上实现了"开-闭"原则。

【例4-4】 已知一个问候程序的算法固定为:先输出问候语字符串,然后再输出被问候者名称字符串,试编写该程序。

(1)分析

经分析可知,程序中的问候语变化并不频繁,基本都为"Hello",而被问候者名称则需经常变化,属于可变性代码,所以要把与被问候者名称相关的代 码隔离出来。这样就使本程序至少需要有两个核心方法:输出问候语方法和输出被问候者名称方法。显然,为了实现题目所要求的字符串输出顺序还应设计一个模板 方法。于是,得到例题类图如图4-10所示。

 
(点击查看大图)图4-10  例题类图
(2) 代码
/*抽象类*/
public abstract class Greeting{
/*默认问候语*/
public void defaultGreeting(){  
System.out.print("Hello ");
}
/*抽象方法*/
public abstract void nameGreeting(String name);
/*模板方法*/
public void Greeting(String name){
defaultGreeting();
nameGreeting(name);
}
}
/*具体实现类*/
public class concretGreeting extends Greeting{
/*实现了抽象方法*/
public void nameGreeting(String name){
System.out.println(name);
}
}
/*测试*/
public class Main{
private static Greeting g=null;
public static void main(String[]args){
g=new concretGreeting();
g.Greeting(args[0]);
}
}

(3)程序运行

输入运行命令时,命令行参数为Renzhe,则程序运行结果如图4-11所示。

 
图4-11  例4-4程序运行结果

(4)当业务逻辑发生变化时,子类的变化

假如,本程序使用了一段时间后,企业业务发生了某种变化,要求在问候之前,需要对被问候人进行检查。如果为新客人,就问候"Hello ×××,本公司真诚欢迎您!";如果为老客人,则问候"Hello ×××,很高兴又见到您!"

显然,为了达到新的要求,只需修改子类concretGreeting中对方法nameGreeting()的实现就可以了,而不会影响算法骨架的 一丝一毫。




阅读(533) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

chulia200020012010-03-22 12:56:37

http://jjhou.csdn.net/myan-design-patterns-big5.htm 与大虾对话: 领悟设计模式--Template Method / Visitor I. Virtually Yours?-- Template Method模式 我在研究Wendy写的一个类。那是她为这个项目写的一个抽象基类,而我的工作就是从中派生出一个具象类(concrete class)。这个类的public部份是这样的: class Mountie { public: void read( std::istream & ); void write( std::ostream & ) const; virtual ~Mountie(); 很正常,virtual destructor表明这个类打算被继承。那麽再看看其protected部份: protected: virtual void do_read( std::istream & ); virtual void do_write( std::ost

chulia200020012010-03-22 12:53:22

http://ajava.org/course/design/15149.html 设计模式之Template Method模式 先简单介绍Template Method模式的内容和应用场景。 Template Method模式也叫模板方法模式,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。 在作为抽象类的父类里,定义了一个具有固定算法并可以细分为多个步骤的模板方法(public),Template Method模式把这些可以被细分的可变步骤抽象为可以被子类重载的抽象方法(protected abstract),并通过在子类中的重载(重新定义),做到无需改变模板方法的算法步骤而可以重新定义该算法中的某些特定的步骤。 Template Method模式的UML图如下: image (注意:版权所有hankchen) Template Method模式一般应用在具有以下条件的应用中: 1. 具有统一的操作步骤或操作过程 2. 具有不同的操作细节 3. 存在多个具有同样操作

chulia200020012010-03-22 12:48:46

url[http://www.blogjava.net/amigoxie/archive/2007/03/20/105110.html] 模板方法(Template Method)模式 属于对象的行为模式。 1. 定义 定义一个操作中算法的骨架,将一些步骤执行延迟到其子类中。模板方法模式是基于继承的代码复用的基本技术,该模式的结构和用法也是面向对象设计的核心。 2. 使用的原因 当一个算法的基本骨架已能确定,但算法的实现部分会根据具体情况有所变动,或为了提高算法实现的灵活性时,可考虑采用模板方法(Template Method)模式。 3. 适用的情况举例 eg. 你计划了向所喜欢的女孩子表白,你已经想好了当晚表白时要进行的具体步骤,例如第一步打电话约该女生出来,第二步与该女生去一家咖啡厅或附近的某公园表白,第三步.......,但还没想好具体的某些步该怎么样做时,你可以先定义一个抽象的模板,然后请各好友或自己闭关想出一种或多种来实现之; 4. 类图结构及说明 1)类图结构如下所示: 2)类说明