架构设计与重构程序员@IT·互联网

设计模式 ——— 模板方法模式

2017-11-11  本文已影响56人  tomas家的小拨浪鼓

TEMPLATE METHOD(模板方法) ———— 类行为型模式

意图

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

适用性

结构

模板方法模式结构图

认识模板方法模式

变与不变

程序设计的一个很重要的思考点就是“变与不变”,也就是分析程序中哪些功能是可变的,哪些功能是不变的,然后把不变的部分抽象出来,进行公共的实现,把变化的部分分离出去,用接口来封装隔离,或者是用抽象类来约束子类行为。

模板方法模式很好的体现了这一点。模板类实现的就是不变的方法和算法的骨架,而需要变化的地方,都通过抽象方法,把具体实现延迟到子类去了,而且还通过父类的定义来约束了子类的行为,从而使系统能有更好的复用性和扩展性。

好莱坞法则

什么是好莱坞法则呢?简单点说,就是“不要找我们,我们会联系你”。

模板方法模式很好的体现了这一点,做为父类的模板会在需要的时候,调用子类相应的方法,也就是由父类来找子类,而不是让子类来找父类。

这其实也是一种反向的控制结构,按照通常的思路,是子类找父类才对,也就是应该是子类来调用父类的方法,因为父类根本就不知道子类,而子类是知道父类的,但是在模板方法模式里面,是父类来找子类,所以是一种反向的控制结构。

对设计原则的体现

模板方法很好的体现了开闭原则和里氏替换原则。

首先从设计上,先分离变与不变,然后把不变的部分抽取出来,定义到父类里面,比如算法骨架,比如一些公共的、固定的实现等等。这些不变的部分被封闭起来,尽量不去修改它了,要扩展新的功能,那就使用子类来扩展,通过子类来实现可变化的步骤,对于这种新增功能的做法是开放的。

其次,能够实现统一的算法骨架,通过切换不同的具体实现来切换不同的功能,一个根本原因就是里氏替换原则,遵循这个原则,保证所有的子类实现的是同一个算法模板(为了防止子类改变模板方法中的算法,可以将模板方法声明为final),并能在使用模板的地方,根据需要,切换不同的具体实现。

模板方法模式的实现

模板方法调用下列类型的操作
模板方法模式实现中指的注意的问题:

① 使用访问控制:必须重定义的原语操作须定义为abstract函数。模板方法自身不需要被重定义,并且也不应该被重定义,为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
② 尽量减少原语操作:定义模板方法的一个重要目的是尽量减少一个子类具体实现算法时必须重定义的那些原语操作的数目。需要重定义的操作越多,客户程序就越冗长。
③ 命名约定:可以给应被重定义的那些操作的名字加上一个前缀以识别它们。

优缺点

优点:
实现代码复用
模板方法模式是一种实现代码复用的很好的手段。通过把子类的公共功能提炼和抽取,把公共部分放到模板里面去实现。

缺点:
算法骨架不容易升级
模板方法模式最基本的功能就是通过模板的制定,把算法骨架完全固定下来。事实上模板和子类是非常耦合的,如果要对模板中的算法骨架进行变更,可能就会要求所有相关的子类进行相应的变化。所以抽取算法骨架的时候要特别小心,尽量确保是不会变化的部分才放到模板中。

相关模式

参考

《Head First 设计模式》
《设计模式:可复用面向对象软件的基础》
《研磨设计模式》

上一篇 下一篇

猜你喜欢

热点阅读