在看Spring的JdbcTemplate的时候,看到其将模板模式和回调模式结合使用的实现,能够精妙的解决不少的问题。详见Spring中涉及的设计模式总结中的关于模板模式和回调模式结合的具分析,本文利用设计思想实现了一个简单的模板+回调的demo算法
所谓模板板式,就是在父类中定义算法的主要流程,而把一些个性化的步骤延迟到子类中去实现,父类始终控制着整个流程的主动权,子类只是辅助父类实现某些可定制的步骤。
模板方法设计模式适用性:
一、一次性实现一个算法的不变部分,并将可变的算法留给子类来实现。
二、各子类中公共的行为应该被提取出来并集中一个公共父类中以免代码重复。 三、能够控制子类扩展。设计模式
模板模式的相关实现详见参考文献ide
上述模板模式存在一个问题,每一个子类都要都要继承一下上面的父类中的抽象方法,这时,经过CallBack(回调)能够解决这种问题。 所谓回调,就是方法参数中传递一个接口,父类在调用此方法时,必须调用方法中传递的接口的实现类。测试
public class AccService { public Object executeAcc(Object req) { // 通用流程 Object result = null; doExecute1(); // 不一样的实现部分 BaseAccReq accReq = doGenAccReq(req); System.out.println(accReq); // 不一样的实现部分 result = doInvoke(accReq); return result; } // 默认实现 BaseAccReq doGenAccReq(Object req) { return null; } // 默认实现 Object doInvoke(BaseAccReq req) { return null; } public BaseAccReq execute(AccReqGenCallBack action, Object req) { // before BaseAccReq accReq = action.doGenAccReq(req); // after return accReq; } public Object execute(AccInvokeCallBack action, BaseAccReq req) { // before Object result = action.doInvoke(req); // after return result; } private void doExecute1() { // doSomething } }
public class GeneralAccService extends AccService { @Override BaseAccReq doGenAccReq(Object req) { final Object test = new Object(); return execute(new AccReqGenCallBack() { @Override public BaseAccReq doGenAccReq(Object req) { GeneralAccReq generalAccReq = new GeneralAccReq(); generalAccReq.setOrdNo("1234"); generalAccReq.setPrdNo("01"); System.out.println(test); // doSomething return generalAccReq; } }, req); } @Override Object doInvoke(BaseAccReq req) { return execute(new AccInvokeCallBack() { @Override public Object doInvoke(BaseAccReq req) { GeneralAccReq generalAccReq = (GeneralAccReq) req; System.out.println(generalAccReq); // call Third Service return new Object(); } }, req); } }
public class AdaptAccService extends AccService { @Override BaseAccReq doGenAccReq(Object req) { final Object test = new Object(); return execute(new AccReqGenCallBack() { @Override public BaseAccReq doGenAccReq(Object req) { AdaptAccReq adaptAccReq = new AdaptAccReq(); adaptAccReq.setOrdNo("1234"); adaptAccReq.setChkNo("02"); System.out.println(test); // doSomething return adaptAccReq; } }, req); } @Override Object doInvoke(BaseAccReq req) { return execute(new AccInvokeCallBack() { @Override public Object doInvoke(BaseAccReq req) { AdaptAccReq adaptAccReq = (AdaptAccReq)req; System.out.println(adaptAccReq); //call Third Service return new Object(); } },req); } }
public interface AccReqGenCallBack { BaseAccReq doGenAccReq(Object req); }
public interface AccInvokeCallBack { Object doInvoke(BaseAccReq req); }
public class BaseAccReq { private String ordNo; public String getOrdNo() { return ordNo; } public void setOrdNo(String ordNo) { this.ordNo = ordNo; } }
public class GeneralAccReq extends BaseAccReq { private String prdNo; public String getPrdNo() { return prdNo; } public void setPrdNo(String prdNo) { this.prdNo = prdNo; } }
public class AdaptAccReq extends BaseAccReq { private String chkNo; public String getChkNo() { return chkNo; } public void setChkNo(String chkNo) { this.chkNo = chkNo; } }
public class TestAcc { public static void main(String[] args) { GeneralAccService generalAccService = new GeneralAccService(); Object req = new Object(); Object result = generalAccService.executeAcc(req); System.out.println(result); AdaptAccService adaptAccService = new AdaptAccService(); Object result2 = adaptAccService.executeAcc(req); System.out.println(result2); } }
参考文献 Spring中的模板模式和回调模式this
回调机制和模板方法.net