一、定义
抽象模板类定义一个流程,将一些步骤的实现推迟到子类中。
模版方法中的两个角色:
抽象父类:定义模版方法,在模版方法的流程中调用了抽象方法。
具体子类:继承抽象父类,实现抽象方法。
推荐关于模版方法模式的好文,那里有最经典的例子:
Java设计模式之模板方法模式(Template Method)
设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
【java设计模式】之 模板方法(Template Method)模式
二、优缺点
优点:
1.减少了子类重复的代码。模版方法把不变的流程代码定义在了超类当中,减少了子类重复的代码。
2.父类代码重用,子类扩展灵活。因为父类控制了子类的扩展,父类定义不变的流程,子类负责不同的实现,不同的子类可以有不同的实现,不同的实现可以应用在不同的环境中。这体现了父类代码的可重用性,子类代码的灵活性。
3.符合开放闭合原则,扩展子类不用修改其它子类,不用修改抽象父类。
优缺点
最大的是代码复用。把公共的方法提取到了父类中,子类只需要实现特定的方法就可以了。
模板方法模式最大的缺点是阅读性差,这一点真是深有感触。即使是我自己编写的插件生成工具,过了半年后再来看,都会变得有点困难。
第二点是模板流程固定,如果要修改流程,那就需要改代码。如果模板定义在JAR包里面,只能重新创建一个新的模板类。
1.代码阅读难度变高。因为不符合平时的设计习惯。一般情况下,我们喜欢定义接口,它的实现类就是实现类,一目了然。使用了模版方法模式后,我们的子类只有抽象方法的实现,而具体的流程还要去它的父类去研究,因此难度比平时高。
这一点我深有体会,当时项目中定义了抽象导出Excel模版类,自己要去继承这个抽象Excel模版,实现定义每列的数据的抽象方法,那段代码看的贼费劲。
2.抽象父类的流程模版比较固定,升级困难。试想,如果现在的需求需要在以前的流程中途添加一步,但是又不允许修改以前模版的流程。这个时候就尴尬了,我们还得重新定义一个新的模版类,重新实现这个新模版。或者继承这个老的模版,毕竟这样可以继承了部分抽象方法。
三、心法
当流程固定不变,具体细节可变的时候,可以考虑使用模版方法模式。
如何控制父类的行为
添加钩子方法。在调用抽象方法之前添加钩子方法,钩子方法返回Boolean,子类可以重写这个钩子方法,用于添加复杂的判断条件。
将模版方法定义为final,禁止子类重写。
只有确定流程固定不变的时候才去使用模版方法模式,否则需求变更玩不死你。
分割线--------------------------------------------------------------------------------------------
下一篇:观察者模式16
刻意练习
(1)模板设计模式的定义(一句话描述)。
(2)模板设计模式优点。
(3)模板设计模式缺点。
(4)类图(脑海过一下)
(5)在设计模板流程中,如何控制父类的行为。