设计模式 ( 十九 ) 模板方法模式Template method(类行为型)

设计模式
( 十九 ) 模板方法模式Template method(类行为型)

1.概述

在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序。但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。
例子1:银行业务办理流程
在银行办理业务时,一般都包含几个基本固定步骤:
取号排队->办理具体业务->对银行工作人员进行评分。
取号取号排队和对银行工作人员进行评分业务逻辑是一样的。但是办理具体业务是个不相同的,具体业务可能取款、存款或者转账。

2.问题

如何保证架构逻辑的正常执行,而不被子类破坏 ?

3.解决方案

模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 T模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。(Template Method Pattern:Definethe skeleton of an algorithm in an operation,deferring
some steps tosubclasses.Template Methodletssubclasses redefine certain steps of an algorithmwithoutchanging the algorithm's structure. )

1)模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。

2)在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。

4.适用性

模板方法应用于下列情况:
• 1) 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
• 2)各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
• 3)控制子类扩展。模板方法只在特定点调用“ hook”操作 ,这样就只允许在这些点进行扩展。

5.结构

6.模式的组成

抽象类(AbstractClass): 定义抽象的原语操作(primitive operation) ,具体的子类将重定义它们以实现一个算法, 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义
具体子类 (ConcreteClass):  实现原语操作以完成算法中与特定子类相关的步骤。

7.效果

模板方法模式的优点:
1)模板方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。
2)模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
3)模板方法模式导致一种反向的控制结构,这种结构有时被称为“好莱坞法则” ,即“别找我们,,我们找你”通过一个父类调用其子类的操作(而不是相反的子类调用父类),通过对子类的扩展增加新的行为,符合“开闭原则”

模板方法模式的缺点:
每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,但是更加符合“单一职责原则”,使得类的内聚性得以提高。

8.实现

我们使用银行业务实现,添加了hook方法,客户自己觉得评价服务。

[php] view
plain
 copy

 print?

  1. <?php  
  2. /** 
  3.  * 模板方法模式: 
  4.  *  
  5.  * @author guisu 
  6.  */  
  7.   
  8. /** 
  9.  * 抽象类 
  10.  */  
  11. abstract class AbstractBank  
  12. {  
  13.     private $_number ;  
  14.     /** 
  15.      *模板方法 
  16.      * 因为子类不能覆写一个被定义为final的方法。从而保证了子类的逻辑永远由父类所控制。 
  17.      * 
  18.      */  
  19.     public final   function templateMethodProcess()    
  20.     {  
  21.         $this->takeNumber();  
  22.         $this->transact();  
  23.         if($this->isEvaluateHook()) {  
  24.             $this->evaluateHook();  
  25.         }  
  26.     }  
  27.     /** 
  28.      * 基本方法—具体方法 
  29.      * 取号 
  30.      * 
  31.      */  
  32.     private  function takeNumber()      
  33.     {  
  34.         return ++$this->_number;  
  35.     }  
  36.     /** 
  37.      *  //基本方法—抽象方法 
  38.      * 
  39.      */  
  40.     protected  abstract function transact();     
  41.     /** 
  42.      * 基本方法—钩子方法 
  43.      * 
  44.      */  
  45.      protected function evaluateHook() {  
  46.         echo ' evaluateHook<br/>';  
  47.      }  
  48.     /** 
  49.      * 基本方法—钩子方法 
  50.      */  
  51.     protected function isEvaluateHook() {  
  52.         return true;  
  53.     }  
  54.   
  55. }   
  56.   
  57. /** 
  58.  * 具体子类:存款 
  59.  */  
  60. class ConcreteDeposit extends AbstractBank  
  61. {  
  62.     public function transact() {  
  63.         //实现代码  
  64.         echo 'Deposit', '<br>';  
  65.     }  
  66. }   
  67.   
  68. /** 
  69.  * 具体子类:取款 
  70.  */  
  71. class ConcreteWithdraw extends AbstractBank  
  72. {  
  73.    public function transact() {  
  74.         //实现代码  
  75.         echo 'Withdraw', '<br>';  
  76.     }  
  77. }   
  78.   
  79. /** 
  80.  * 具体子类:转账 
  81.  */  
  82. class ConcreteTrancfer extends AbstractBank  
  83. {  
  84.     public function transact() {  
  85.         //实现代码  
  86.         echo 'Trancfer', '<br>';  
  87.     }  
  88. }   
  89. $c = new  ConcreteTrancfer();  
  90. $c->templateMethodProcess();  

9.与其他相关模式

1)策略模式:模板方法使用继承来改变算法的一部分。 Strategy使用委托来改变整个算法。模板方法模式与策略模式的作用十分类似,有时可以用策略模式替代模板方法模式。模板方法模式通过继承来实现代码复用,而策略模式使用委托,把不确定的行为集中到一个接口中,并在主类委托这个接口。委托比继承具有更大的灵活性。

10.模式的扩展

1)模板方法模式与控制反转(好莱坞原则)在模板方法模式中,子类不显式调用父类的方法,而是通过覆盖父类的方法来实现某些具体的业务逻辑,父类控制对子类的调用,这种机制被称为好莱坞原则(Hollywood
Principle),好莱坞原则的定义为:“不要给我们打电话,我们会给你打电话(Don‘t
call us, we’ll call you)”。在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。模板方法模式充分的体现了“好莱坞”原则。由父类完全控制着子类的逻辑,子类不需要调用父类,而通过父类来调用子类,子类可以实现父类的可变部份,却继承父类的逻辑,不能改变业务逻辑。

2)模板方法模式符合开闭原则

模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用,同时也遵守了开闭原则。

父类通过顶级逻辑,它通过定义并提供一个具体方法来实现,我们也称之为模板方法。通常这个模板方法才是外部对象最关心的方法。在上面的银行业务处理例子中,templateMethodProcess这个方法才是外部对象最关心的方法。所以它必须是public的,才能被外部对象所调用。

子类需要继承父类去扩展父类的基本方法,但是它也可以覆写父类的方法。如果子类去覆写了父类的模板方法,从而改变了父类控制的顶级逻辑,这违反了“开闭原则”。我们在使用模板方法模式时,应该总是保证子类有正确的逻辑。所以模板方法应该定义为final的。所以AbstractClass类的模板方法templateMethodProcess方法应该定义为final。

模板方法模式中,抽象类的模板方法应该声明为final的。因为子类不能覆写一个被定义为final的方法。从而保证了子类的逻辑永远由父类所控制。

3)模板方法模式与对象的封装性

面向对象的三大特性:继承,封装,多态。

对象有内部状态和外部的行为。封装是为了信息隐藏,通过封装来维护对象内部数据的完整性。使得外部对象不能够直接访问一个对象的内部状态,而必须通过恰当的方法才能访问。

对象属性和方法赋予指定的修改符(public、protected、private)来达到封装的目的,使得数据不被外部对象恶意的访问及方法不被错误调用导造成破坏对象的封装性。

降低方法的访问级别,也就是最大化的降低方法的可见度是一种很重要的封装手段。最大化降低方法的可见度除了可以达到信息隐藏外,还能有效的降低类之间的耦合度,降低一个类的复杂度。还可以减少开发人员发生的的错误调用。

一个类应该只公开外部需要调用的方法。而所有为public方法服务的方法都应该声明为protected或private。如是一个方法不是需要对外公开的,但是它需要被子类进行扩展的或调用。那么把它定义为protected.否则应该为private。

显而易见,模板方法模式中的声明为abstract的基本操作都是需要迫使子类去实现的,它们仅仅是为模板方法服务的。它们不应该被抽象类(AbstractClass)所公开,所以它们应该protected。

因此模板方法模式中,迫使子类实现的抽象方法应该声明为protected abstract。

4)模板方法与勾子方法(hookMethod)

模板方法模式的抽象类定义方法:

模板方法:一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。

基本方法:基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法如下:

抽象方法(Abstract Method)

•具体方法(Concrete Method)

•钩子方法(Hook Method):“挂钩”方法和空方法,

hook方法在抽象类中的实现为空,是留给子类做一些可选的操作。如果某个子类需要一些特殊额外的操作,则可以实现hook方法,当然也可以完全不用理会,因为hook在抽象类中只是空方法而已。

1)钩子方法的引入使得子类可以控制父类的行为。

2)最简单的钩子方法就是空方法,也可以在钩子方法中定义一个默认的实现,如果子类不覆盖钩子方法,则执行父类的默认实现代码。

3)比较复杂一点的钩子方法可以对其他方法进行约束,这种钩子方法通常返回一个boolean类型,即返回true或false,用来判断是否执行某一个基本方法。由子类来决定是否调用hook方法。

11.总结与分析

1)模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系。

2)板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。

3)在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。

时间: 2024-10-26 05:49:14

设计模式 ( 十九 ) 模板方法模式Template method(类行为型)的相关文章

乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)

原文:乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern) 作者:webabcd 介绍 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 示例 有一个Message实体类,对它的操作有Get()方法,每次Get()之前要使用ValidateUs

.Net设计模式实例之模板方法模式(Template Mothed Pattern)

一.模板方法模式简介(Brief Introduction) 模板方法模式(Template Method Pattern),定义一个操作中的算法骨架,而将一些步骤 延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可以重定义算法的某些特定 步骤.模板方法模式把不变行为搬移到超类,从而去除子类中的重复代码,实际上模板方法 模式就是提供了一个代码复用平台. 二.解决的问题(What To Solve) 要完成在某一细节上层次一致的一个过程或一系列步骤,但个别步骤在更详细的层次上 实现不同时,

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述         在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件判断语

【java设计模式】之 模板方法(Template Method)模式

版权声明:尊重博主原创文章,转载请注明出处哦~http://blog.csdn.net/eson_15/article/details/51323902 目录(?)[+] 1. 模板方法的一个实例         这一节主要来学习一下设计模式中的模板方法模式.我们先来看一个例子:假如现在老板让你做一个汽车的模型,要求只要完成基本功能即可,不考虑扩展性,那你会怎么做呢?我们首先会根据经验设计一个类图:        由这个类图可知,非常简单的实现了悍马车,该车有两个型号H1和H2.那现在我们开始实

解读设计模式----模板方法模式(Template Method)

一. 模式概述 摸板方法(Template Method)模式是一种非常简单而又经常使用的设计模式.先创建一个父类,把其中的一个或多个方法留给子类去实现,这实际上就是在使用摸板模式.所谓的摸板模式可以这样来理解:"在一个类中定义一个算法,但将此算法的某些细节留到子类中去实现.换句话说,基类是一个抽象类,那么你就是在使用一种简单形式的摸板模式." 更近一步可以这样来理解:"准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可

设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)

1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的有用方法,但通常你会处理一组对象或者集合. 集合不一定是均一的.图形用户界面框架中的 Window 对象可以收集任意数量的控制对象 - Menu.Slider 和 Button.并且,集合的实现可以有多种方式:PHP 数字是一个集合,但也是一个散列表,一个链接列表,一个堆栈以及队列. 例子1:电视遥控器的频道遍历 2.问题 如何操纵任意的对象集合?  如一个列表(Li

设计模式中的模板方法模式在Ruby中的应用实例两则_ruby专题

实例一今天你还是像往常一样来上班,一如既往地开始了你的编程工作. 项目经理告诉你,今天想在服务器端增加一个新功能,希望写一个方法,能对Book对象进行处理,将Book对象的所有字段以XML格式进行包装,这样以后可以方便与客户端进行交互.并且在包装开始前和结束后要打印日志,这样方便调试和问题定位. 没问题!你觉得这个功能简直是小菜一碟,非常自信地开始写起代码. Book对象代码如下: class Book attr_accessor :book_name, :pages, :price, :aut

java-23种设计模式中,模板方法模式体现了什么原则,求大神

问题描述 23种设计模式中,模板方法模式体现了什么原则,求大神 百度上看到有人说是 单一职责原则和开放封闭原则.开放封闭原则我懂,可是单一职责原则真的有吗?子类继承了父类,实现父类的方法中的具体操作,不同的子类类型有不同的实现方式,这好像不是单一职责原则的意义啊.还是说体现了其他原则?求大神,谢谢各路英雄好汉 解决方案 1)模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系. 2)板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计

乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)

原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) 作者:webabcd 介绍 定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例 有SqlMessage和XmlMessage,用Factory Method来实例化它们. MessageModel using Syst