本文简单讲述了模板方法模式, 例子为如何使作文模板来写作文. 如果想进一步, 了解模板方法, 建议读完后阅读一下 spring 中 AbstractApplicationContext 类的 refresh 方法或 HttpServelt 类中的 service 方法.
一, 概念
定义: 模板方法模式 (Template method pattern) 是一种类的行为设计模式. 该模式会在父类的一个操作中定义算法的结构, 然后将具体实现推迟到子类中完成. 可以让子类重新定义某些方法的实现而不改变原来的算法结构.
当然, 父类可以实现该算法结构的某些方法, 将剩余逻辑交给子类实现, 不同的子类有不同的实现.
模板方法模式是最常被使用的设计模式之一, 在 Servlet 里, 记不记的我们要继承一个 HttpServlet 类, 然后需要重写 doPost()和 doGet()方法. 还有那个 Spring 的 IoC 容器的初始化方法中 refresh()就是一个典型的模板方法, 这里面 obtainFreshBeanFactory()是抽象方法, postProcessBeanFactory()和 onRefresh()是钩子方法.
二, 结构
UML 图:
主要组成部分:
抽象模板类(Template): 会定义一个模板方法, 模板方法往往是一个具体方法, 给出一个固定的方法调用顺序, 其中的抽象方法会推迟到子类中实现.
Template: 模板方法, 会定义一个逻辑骨架
method01: 具体方法, 在抽象类中就给出了实现, 如果不想让子类修改, 可以给方法加上 final
method02: 抽象方法, 推迟到子类中实现, 在不同的子类中可以有不同的实现
hook: 钩子方法, 抽象类给出了默认实现, 子类也可以根据需要对该方法进行重写
抽象类实现(SubClass): 模板类中的抽象方法会在子类中实现, 不同的子类中算法会有不同的实现, 其中 SubClass2 选择了重写 hook 方法, 而 SubClass1 选择了抽象类中默认实现.
三, 谁又没背过几篇作文模板呢?
都是应试教育过来的人, 想必大家都背过几个作文模板吧~ 哈哈, 接下来, 我们就用模板方法模式做一个简单的作文模板!
这是个作文模板, 也就是模板方法模式里面的抽象类, start 和 end 都是钩子方法, content 是抽象方法, 需要推迟到子类中实现
- public abstract class CompositionTemplate {
- public void template(){
- start();
- content();
- end();
- }
- public void start(){
- System.out.println("As far as I am concerned,");
- }
- public void end(){
- System.out.println("In a word,");
- }
- public abstract void content();
- }
一篇关于保护环境的文章
- public class Composition1 extends CompositionTemplate {
- @Override
- public void content() {
- System.out.println("李华认为保护环境很重要!");
- }
- }
一篇关于经济的文章
- public class Composition2 extends CompositionTemplate {
- @Override
- public void content() {
- System.out.println("小白认为经济发展更重要!");
- }
- }
搞起来~
- public class Test {
- public static void main(String[] args) {
- CompositionTemplate composition1 = new Composition1();
- CompositionTemplate composition2 = new Composition2();
- composition1.template();
- System.out.println("--------------");
- composition2.template();
- }
- }
- ------>
- As far as I am concerned,
李华认为保护环境很重要!
- In a Word,
- --------------
- As far as I am concerned,
小白认为经济发展更重要!
In a Word,
看有了模板之后, 我们只需要在不同的文章里将中间的 content 部分重写就可以了, 如果同学姿势水平比较高, 那就连开头结尾的两个钩子方法也重写了, 哈哈~
我自己写这个模板方法, 不要太简单, 大家如果感兴趣, 我强烈建议看一下 HttpServlet 里面的 service 方法, 这是一个很经典模板方法模式, 里面的 doPost,doGet,doDelete 等等, 都是钩子方法, 在抽象类里有默认实现, 在子类中可以重写.
另外, 值得注意的是, 钩子方法的命名规则是 doXXX, 这是熟悉设计模式的开发人员的默认做法, 以后如果使用钩子方法时, 记得这样命名, 你和其他开发人员就更方便沟通了~
四, 优缺点
优点
提高代码的复用性, 相同的逻辑部分会在抽象类中实现
提高代码扩展性, 将不同部分放入子类, 如果需要扩展, 可以添加新的子类
符合好莱坞原则, 由抽象类主控一切, 子类绝不直接调用抽象类.
缺点
引入了抽象类, 每一个不同的实现都需要一个子类来实现, 导致类的个数增加, 从而增加了系统实现的复杂度.
五, 总结
模板方法模式是经常用到的一种设计模式, 但也是很容易理解的一种模式. 重点在抽象模板类中的模板方法主控一切, 需要改变的抽象方法推迟到子类中完成.
值得注意的是, 不要与策略模式混淆, 策略模式同样也是封装算法, 但是策略模式是封装整个算法, 而模板方法模式是将需要改变的部分在子类中实现; 策略方法使用组合, 而模板方法是使用继承.
Head First 设计模式, Eric Freeman &Elisabeth Freeman with Kathy Sierra & Bert Bates http://product.dangdang.com/20021171.html
Template method pattern,wiki
《JAVA 与模式》之模板方法模式
来源: https://www.cnblogs.com/cdream-zs/p/10140112.html