在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。 介绍
意图:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。主要解决:
一些方法通用,却在每一个子类都重新写了这一方法。何时使用:
有一些通用的方法。如何解决:
将这些通用算法抽象出来。关键代码:
在抽象类实现,其他步骤在子类实现。应用实例 :
1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。2、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。优点 :
1、封装不变部分,扩展可变部分。2、提取公共代码,便于维护。3、行为由父类控制,子类实现。缺点:
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。使用场景 :
1、有多个子类共有的方法,且逻辑相同。2、重要的、复杂的方法,可以考虑作为模板方法。注意事项:
为防止恶意操作,一般模板方法都加上 final 关键词下面使用豆浆制作的案例演示
创建豆浆的抽象类,并定模板方法和可决定模板方法流程的钩子方法
/** 抽象类标识豆浆 */ public abstract class SoyaBeanMilk { /** 模板方法可以做成final , 不让子类去覆盖. */ final void make() { select(); if (customerWantCondiments()) { addCondiments(); } soak(); beat(); } // 选材料 void select() { System.out.println("第一步:选择好的新鲜黄豆 "); } // 添加不同的配料, 抽象方法, 子类具体实现 abstract void addCondiments(); // 浸泡 void soak() { System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时 "); } void beat() { System.out.println("第四步:黄豆和配料放到豆浆机去打碎 "); } /** * 钩子方法,决定是否需要添加配料 默认添加调料 * * @return */ protected boolean customerWantCondiments() { return true; } }实现不同的豆浆类
/** 花生豆浆 */ public class PeanutSoyaMilk extends SoyaBeanMilk { @Override void addCondiments() { System.out.println(" 加入上好的花生 "); } } /** 红豆豆浆 */ public class RedBeanSoyaMilk extends SoyaBeanMilk { @Override void addCondiments() { System.out.println(" 加入上好的红豆 "); } }客户端
public class Client { public static void main(String[] args) { System.out.println("----制作红豆豆浆----"); SoyaBeanMilk redBeanSoyaMilk = new RedBeanSoyaMilk(); redBeanSoyaMilk.make(); System.out.println("----制作花生豆浆----"); SoyaBeanMilk peanutSoyaMilk = new PeanutSoyaMilk(); peanutSoyaMilk.make(); } }