第九式 模板方法模式
模板方法模式
认识模板方法模式
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
这个模式是用来创建一个算法的模板。什么是模板?模板就是一个固定的方法。更具体的说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,
由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。
类图:
解决一个问题
很多事情都是有一个固定步骤的,比如泡茶或者咖啡,都要烧水,都要装杯。下面用模板方法模式展示一下
创建一个冲饮料模板,将加什么饮料和加什么调味料方法抽象
public abstract class Drinking { public void createDrinking(){ prepareHotWater(); brew(); addCondiments(); pourIntoCup(); } public void prepareHotWater(){ System.out.println("烧热水"); } public abstract void brew(); public abstract void addCondiments(); public void pourIntoCup(){ System.out.println("将喝的倒入杯中"); } }
创建泡茶类
public class Tea extends Drinking { @Override public void brew() { System.out.println("加入茶叶"); } @Override public void addCondiments() { System.out.println("加入牛奶"); } }
创建冲咖啡类
public class Coffee extends Drinking { @Override public void brew() { System.out.println("加入咖啡"); } @Override public void addCondiments() { System.out.println("加入牛奶和方糖"); } }
客户端测试
public static void main(String[] args){ Tea tea = new Tea(); tea.createDrinking(); System.out.println("-------------------------"); Coffee coffee = new Coffee(); coffee.createDrinking(); }
运行结果:
烧热水
加入茶叶
加入牛奶
将喝的倒入杯中
-------------------------
烧热水
加入咖啡
加入牛奶和方糖
将喝的倒入杯中
模板方法模式的应用
优点:
1.封装不变部分,扩展可变部分
2.提取公共部分代码,便于维护
3.行为由父类控制,子类实现
缺点:
按照正常的设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法。但模板方法模式却颠倒了,抽象类
定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,子类对父类产生了影响,这在复杂的项目中,会带来代码阅读的难度,而且也会
让新手产生不适感。另外每一个不同的实现都需要一个子类来实现,导致类的个数增加,也会使得系统更加庞大和复杂。
使用场景:
1.多个子类有共有的方法,并且逻辑基本相同
2.重要、复杂的算法,可以把核心算法设计成模板方法,周边的相关细节功能则由各个子类实现
3.重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为
应用实例:
1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。
2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。
3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。
注意事项:为防止恶意操作,一般模板方法都加上 final 关键词