设计模式(java实现)_模板方法模式(Template method)
模板方法模式是编程中经常用到到的模式。它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。这样,新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。
核心:处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不能确定。因此,可以将该节点的代码实现转移给子类完成。即:处理步骤父类定义好,具体实现延迟到子类中定义,由父类进行整个过程的控制。
使用场景:实现一个算法时,整体步骤很固定,但是某些部分易变。易变部分可以抽象出来,供子类实现。
比如一个场景:
玩氪金手游充钱抽卡的流程。可以确定的是
第一步:打开氪金界面。
第二步:选择氪金。
第三步:选择支付方式。
最后:抽奖。
假设其他流程均为固定,而其中只有选择支付方式这一点可能会有所变化。比如可以用支付宝、微信等等支付。
那么要实现这种需求,每种方式都重复进行一遍编写的话代码太多,过于丑陋。
这时即可使用模板方法模式,将其固定的流程定死,并将选择支付方式声明为抽象,强制子类实现。
代码实现:
氪金的模板方法,可以看见我实现了除【选择支付方式】以外其余所有的方法。并且将流程控制在内部。
子类的权限只够修改除了执行整个氪金流程以外的方法。并且需要强制实现选择支付方式的方法。
package com.skypyb.templateMethod; /** * 模板方法模式 * * @author pyb www.skypyb.com www.yibobo.top */ public abstract class RechargeTemplateMethod { public void entryRechargePage() { System.out.println("进入充值界面..."); } public void recharge() { System.out.println("氪金!"); } //支付方式,具体的支付方式可能变动。abstract修饰,强制子类重写。 public abstract void modeOfPayment(); public void luckyDraw() { System.out.println("抽奖,哇又是保底SR"); } /** * 模板方法,流程已知。 * 定义好具体的流程加上 final 修饰,使得子类不可重写 * 外部调用必须通过本类进行调用 */ public final void process(){ this.entryRechargePage(); this.recharge(); this.modeOfPayment(); this.luckyDraw(); } }
实现其抽象方法的具体类以及客户端调用者:
若实现模板方法的子类并不复杂的话可考虑将其写成匿名内部类。若算法特别复杂并且需要实现的抽象的方法不止一个,那还是老老实实写个子类继承比较好。
package com.skypyb.templateMethod; /** * 模板方法中该节点的实现比较复杂的话可以这样,定义一个专门的类来继承 * @author pyb www.skypyb.com www.yibobo.top */ public class AlipayTemplate extends RechargeTemplateMethod { @Override public void modeOfPayment() { System.out.println("用支付婊付钱"); } }
package com.skypyb.templateMethod; /** * 客户端,即具体使用者 * 可根据需要使用不同的模板实现 * * */ public class Client { public static void main(String[] args) { RechargeTemplateMethod method = new AlipayTemplate(); method.process();//支付婊 System.out.println(); method = new WeChatTemplate(); method.process();//weChat System.out.println(); /** * 匿名内部类实现 */ new RechargeTemplateMethod() { @Override public void modeOfPayment() { System.out.println("用 PY 付钱"); } @Override public void luckyDraw() { System.out.println("抽到SSR辣!"); } }.process(); } /** * 内部类方式实现 */ static class WeChatTemplate extends RechargeTemplateMethod { @Override public void modeOfPayment() { System.out.println("用 WeChat 付钱"); } } }
System.out:
进入充值界面…
氪金!
用支付婊付钱
抽奖,哇又是保底SR
进入充值界面…
氪金!
用 weChat 付钱
抽奖,哇又是保底SR
进入充值界面…
氪金!
用 PY 付钱
抽到SSR辣!
我写的代码只是最简单的,进行举例用。模板方法模式在生产中应用有可能不止一个 abstract method。
甚至子类不止要重写抽象方法,非抽象的方法也有可能选择性重写。
但是,就算其每个节点变化多端,只要执行流程还是固定的,使用该模式肯定能让编码效率、维护效率、扩展效率更上一层楼。