一、模式解析
准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意
模板模式的关键点为:
1、有一个父类,将整体业务逻辑和公用方法进行封装;
2、父类将具体的有差异的业务定义为抽象方法;
3、子类继承父类后,实现这些抽象方法,完成对自己业务流程的;
4、子类不可以改变父类的整体业务逻辑流程;
5、子类也可以覆盖父类中其他方法,实现定制化业务
二、模式代码
父类抽象类
package template.patten; public abstract class AbstractTemplate { //业务逻辑执行 public void templateMethod(){ abstractMethod(); hookMethod(); concreteMethod(); } //抽象方法,需要子类进行覆盖 protected abstract void abstractMethod(); //钩子方法,可以被子类覆盖 protected void hookMethod() { System.out.println("我是模板中的hook方法"); } //父类的具体方法,不可以被重写 private void concreteMethod(){ System.out.println("我是父类的具体方法不能被重写"); } }
子类实现具体业务逻辑
package template.patten; public class ConcreteTemplate extends AbstractTemplate { @Override public void hookMethod() { System.out.println("先调用子类实现的hookmethod,然后再调用父类的方法"); super.hookMethod(); } @Override protected void abstractMethod() { System.out.println("抽象方法的具体实现"); } }
客户端调用
package template.patten; public class Client { public static void main(String[] args) { AbstractTemplate template=new ConcreteTemplate(); template.templateMethod(); } }
三、应用场景
目前工作中,对业务功能的实现主要依赖于模板模式的定义,将所有业务分为几种模板进行定义:
1、查询模板
2、界面初始化模板
3、空模板
4、两步模板
其中两步模板最为复杂,依次举例说明
两步模板-工作中常用的模板之一,主要用于需要修改数据的交易,假设通常内部操作为如下步骤
1、检查数据正确性
2、记录交易日志,将状态修改为进行中
3、进行交易操作
4、根据交易结果,修改交易日志
那么对于一个功能来讲,记录日志和修改交易结果为相对固定的操作,因此封装在模板里,检查交易正确性和进行交易每个交易均不同,所以需要由具体功能进行实现
四、应用代码
package template.example; /** * @author zjl * @time 2016-1-28 * */ public abstract class TwoPhaseTrsTemplate { public void execute() { prepare(); preAction(); submit(); afterAction(); } public abstract void prepare(); public abstract void submit(); private void preAction(){ System.out.println("交易开始,交易状态为进行中,记录交易日志"); } private void afterAction(){ System.out.println("交易成功,更新交易日志状态为成功"); } }
具体交易,以转账为例:
package template.example; public class Transfer extends TwoPhaseTrsTemplate { @Override public void prepare() { System.out.println("检查所有转账元素"); } @Override public void submit() { System.out.println("转账操作,银行核心进行扣帐操作"); } }
客户端调用
package template.example; public class Client { public static void main(String[] args) { Transfer transfer=new Transfer(); transfer.execute(); } }
执行结果:
检查所有转账元素
交易开始,交易状态为进行中,记录交易日志
转账操作,银行核心进行扣帐操作
交易成功,更新交易日志状态为成功