模板办法模式
行为型模式
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的办法的形式/模板。它的子类能够按须要重写办法实现,但调用将以抽象类中定义的形式进行。
介绍
用意: 定义一个操作中的算法的骨架,而将一些步骤提早到子类中。模板办法使得子类能够不扭转一个算法的构造即可重定义该算法的某些特定步骤。
次要解决: 一些办法通用,却在每一个子类都从新写了这一办法。
何时应用: 有一些通用的办法。
如何解决: 将这些通用算法形象进去。
要害代码: 在抽象类实现,其余步骤在子类实现。
具体实现
制作豆浆的流程 选材-->增加配料-->浸泡-->放到豆浆机打碎。
选材、浸泡和放到豆浆机打碎对于制作每种口味的豆浆都是一样。
第一步:创立豆浆模板类
public abstract class SoyaMilk { //模板办法 , make , 模板办法能够写成final,不让子类去笼罩. final void make() { select(); addCondiments(); soak(); beat(); } //选资料 void select() { System.out.println("抉择陈腐的黄豆..."); } //增加不同的配料 abstract void addCondiments(); //浸泡 void soak() { System.out.println("黄豆和配料开始浸泡..."); } //浸泡 void beat() { System.out.println("黄豆和配料放到豆浆机开始打碎..."); }}
第二步:创立不同口味的豆浆
public class RedBeanSoyaMilk extends SoyaMilk { @Override void addCondiments() { System.out.println("退出最好的红豆"); }}
public class PeanutSoyaMilk extends SoyaMilk { @Override void addCondiments() { System.out.println("退出最好的花生"); }}
第三步:创立测试类
public class Client { public static void main(String[] args){ //制作红豆豆浆 System.out.println("---------制作红豆豆浆------"); SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk(); redBeanSoyaMilk.make(); //制作花生豆浆 System.out.println("---------制作花生豆浆------"); SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk(); peanutSoyaMilk.make(); }}
运行如下:
---------制作红豆豆浆------抉择陈腐的黄豆...退出最好的红豆黄豆和配料开始浸泡...黄豆和配料放到豆浆机开始打碎...---------制作花生豆浆------抉择陈腐的黄豆...退出最好的花生黄豆和配料开始浸泡...黄豆和配料放到豆浆机开始打碎...
但这样仿佛有个问题,如果咱们想喝原味不加任何调料的豆浆该怎么办?
钩子办法
大抵流程其实都是一样的,只是减少了一层判断。
第一步:创立豆浆模板类
public abstract class SoyaMilk { //模板办法 , make , 模板办法能够写成final,不让子类去笼罩. final void make() { select(); if(customerWantCondiments()){ addCondiments(); } soak(); beat(); } //选资料 void select() { System.out.println("抉择陈腐的黄豆..."); } //增加不同的配料 abstract void addCondiments(); //浸泡 void soak() { System.out.println("黄豆和配料开始浸泡..."); } //浸泡 void beat() { System.out.println("黄豆和配料放到豆浆机开始打碎..."); } //减少钩子办法,决定是否须要增加配料 boolean customerWantCondiments() { return true; }}
第二步:创立不同口味的豆浆
public class RedBeanSoyaMilk extends SoyaMilk { @Override void addCondiments() { System.out.println("退出最好的红豆"); }}
public class PeanutSoyaMilk extends SoyaMilk { @Override void addCondiments() { System.out.println("退出最好的花生"); }}
public class PureSoyaMilk extends SoyaMilk { @Override void addCondiments() { //空实现 } @Override boolean customerWantCondiments() { return false; }}
第三步:创立测试类
public class Client { public static void main(String[] args){ //制作红豆豆浆 System.out.println("---------制作红豆豆浆------"); SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk(); redBeanSoyaMilk.make(); //制作花生豆浆 System.out.println("---------制作花生豆浆------"); SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk(); peanutSoyaMilk.make(); //制作纯豆浆 System.out.println("---------制作纯豆浆------"); SoyaMilk pureSoyaMilk = new PureSoyaMilk(); pureSoyaMilk.make(); }}
运行如下:
---------制作红豆豆浆------抉择陈腐的黄豆...退出最好的红豆黄豆和配料开始浸泡...黄豆和配料放到豆浆机开始打碎...---------制作花生豆浆------抉择陈腐的黄豆...退出最好的花生黄豆和配料开始浸泡...黄豆和配料放到豆浆机开始打碎...---------制作纯豆浆------抉择陈腐的黄豆...黄豆和配料开始浸泡...黄豆和配料放到豆浆机开始打碎...
长处:
1、封装不变局部,扩大可变局部。 2、提取公共代码,便于保护。 3、行为由父类管制,子类实现。
毛病:
每一个不同的实现都须要一个子类来实现,导致类的个数减少,使得零碎更加宏大。