老生常谈:模板方法模式

     在23种设计模式中,个个都是经典,个个都身怀绝技,各有所长.各具风格的特别注定了它们自身的复杂度以及实现过程.

     在前面的文章中,我谈到了设计模式到底离我们有多远,文章中得到了园友xiaotie的指点:

     ----------------------------------------引用--------------------------------------------------------

     分两种情况来看:

        (1)使用:当你写一个页面时,你已经在用模板模式了,当你写一个事件的时候,你已经在用观察者模式了,当你在用正则表达式时,你已经在用门面模式了。

       (2)实现:当你写一个泛型类或泛型方法的时候,你极有可能正在实现策略模式(可能自己还没感觉到),理解策略模式会让你的泛型程序写的很好。此外,什么wrapper,享元啊,迭代器啊,都是经常会用上的。

------------------------------------------------------------------------------------------------------------

  

      说的不无道理,其实设计模式中也有比较简单的,就比如我今天要说的模板方法模式.

      这是一个很简单的模式,却被非常广泛的使用。之所以简单是因为在这个模式中仅仅使用到了继承关系。设计模式中大多都提倡面向接口编程,用组合来代替继承,但模板方法模式中与之相反应用了继承.这不是自相矛盾吗?之所有大家有这种想法,可能是因为道听途说,大家都说继承如何如何的不好,是恶梦,以讹传讹.其实继承也有自身的优点,一个事物的存在总有它的道理,只不过我们被它平时的滥用造成的缺点吓跑了.

  

     GOF模板方法模式定义:

         一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

    可以看出模板方式非常成功的实现了变化对系统的影响,使系统的扩展性增强,降低了小变化对系统的影响程度.

   模板方法模式由两部分构成:

    第一部分:有两种情况:

  1) :AbstractClass(抽象类):定义了一到多个的抽象方法,由子类来实现它们,包含一个模板方法,它定义一个算法的骨架(可变与不可变部分)。

     2) :并不一定要为抽象类,只要定义一到多个虚方法,以供子类来重写它们,并且同样包含一个模板方法,它定义一个算法的骨架(可变与不可变部分).

    第二部分:有两种情况

   1):ConcreteClass(具体类):实现父类中的抽象方法以完成算法中与特定子类相关的步骤。

     2):ConcreteClass(具体类):重写父类中的虚方法以完成算法中与特定子类相关的步骤。

     至于模板方法模式的类图,简单的让人无法相信它也算是设计模式,这里直接引用GOF中的类图,供大家参考:


    

    当你在新建一个页面,同时它会默认继承Web.UI.Page,这种情况就是使用到了模板方法模式.我们可以重写很多Page类的方法,在另类动态加载控件一文中,我就重写了Page类的AddParsedSubObject方法:

Code

     这里只选择性的重写了Page中的一个方法,其它的虚方法在没有重写前都默认调用父类方法.同时子类会继承父类中所有固定不变的方法,这样就使得子类在具有父类相同功能的同时又具有父类不具备的功能特点.同时充分利用了父类的资源,使得代码得到复用.这个设计模式并没有太多高深的内容可言,只能用一句广告词来形容:简约而不简单.只可意会.MS在自己的产品中经常用到这些让人敬畏的设计模式,如果我们平时稍加注意就会发现设计模式也是那么的平易近人.

     模板方法模式的特点:

      1:它定义了一系列固定且不可变的算法.可变的部分由子类实现.
      2:子类扩展行为具有一定的局限,只能扩展父类中的抽象方法,或者是虚方法.
      3:继承的应用使得代码的复用性加强.
      4:适用于算法结构基本固定的情况.

      5:父类的模板方法控制子类的具体实现,使得我们不用过于关心父类的全部业务流程。

     总结:正如模板方法模式的特点四,如果一个功能点变化的地方过多,那么模板方法可能并不是最好的选择.例如服装城里面的石膏人体模型,它们在制做完成后,身高,三围,性别都是固定的,可变的只是它身上的服饰,如果设想这个模型连身高,三围等都会变化,那服装工厂有可能做出这样的模型吗?起码难度不小。


    

     注: 本文引用:


       http://www.cndw.com/tech/program/2006042861822.asp

原文地址:https://www.cnblogs.com/ASPNET2008/p/1278285.html