模板方法模式是一种十分常见的设计模式,阅读源码是可以说是处处可见。在日常的工作代码编写中也经常使用。这里来记录一下。模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
模板方法模式
这个设计模式的主要思想是当某个方法中一部分具有重复性时,可以将重复部分代码提取在父类中实现,而将变化的部分延迟至子类中实现。
基本类代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public abstract class AbstractClass { protected abstract void doAnything(); protected abstract void doSomething(); public final void templateMethod(){
this.doAnything(); this.doSomething(); } } public class ConcreteClass1 extends AbstractClass {
@Override protected void doAnything() { }
@Override protected void doSomething() { } } public class ConcreteClass2 extends AbstractClass {
@Override protected void doAnything() { }
@Override protected void doSomething() { } }
public static void main (){ AbstractClass a = new ConcreteClass1(); AbstractClass b = new ConcreteClass2(); a.templateMethod(); b.templateMethod(); }
|
实际应用
旧代码
最近调到了新部门,发现后台Service层代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| protected void doAction(RequestBean requestBean, ResponseBean responseBean) throws Exception { Map sysMap = requestBean.getSysMap(); String oper_type = (String) sysMap.get("oper_type"); if (AOSConstants.OPERATE_QUERY.equals(oper_type)) { queryOperation(requestBean,responseBean); } else if (AOSConstants.OPERATE_MODIFY.equals(oper_type)) { modifOperation(requestBean,responseBean); } else if (AOSConstants.OPERATE_ADD.equals(oper_type)) { addOperation(requestBean,responseBean); } else if (AOSConstants.OPERATE_DELETE.equals(oper_type)) { deleteOperation(requestBean,responseBean); } else if ("query_flow".equals(oper_type)){ queryDetailOperation(requestBean,responseBean); } else if ("sel_user".equals(oper_type)) { roleInfo(requestBean, responseBean); } else if ("sel_elem".equals(oper_type)) { selectElems(requestBean, responseBean); } }
|
可以看到,Service层处理业务逻辑时是根据前端传过来的参数去调用不同方法,而增删改查部分的操作标志是固定不变的。这就意味着需要每次去编写相同的条件判断语句,十分不简洁。于是就想到了可以使用模板方法模式+内部类来进行改写。
改进代码
可以在模板类中定义类似于doAction
中的算法骨架,然后在Service中生成匿名类去定义变化部分的方法实现:
模板类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public abstract class TemplateService {
protected Logger logger = LoggerFactory.getLogger(getClass());
private static final String OPERTYPE = "oper_type";
public void operate(RequestBean requestBean, ResponseBean responseBean) throws Exception { Map sysMap = requestBean.getSysMap(); String operateType = (String) sysMap.get(OPERTYPE); if (BaseUtil.isBlank(operateType)) { logger.error("参数{}为空", OPERTYPE); throw new Exception(); } switch (operateType) { case AOSConstants.OPERATE_QUERY: operateQuery(requestBean, responseBean, operateType); break; case AOSConstants.OPERATE_MODIFY: operateModify(requestBean, responseBean, operateType); break; case AOSConstants.OPERATE_ADD: operateAdd(requestBean, responseBean, operateType); break; case AOSConstants.OPERATE_DELETE: operateDelete(requestBean, responseBean, operateType); break; default: operateOther(requestBean, responseBean, operateType); } }
public abstract void operateModify(RequestBean requestBean, ResponseBean responseBean, String operateType);
public abstract void operateQuery(RequestBean requestBean, ResponseBean responseBean, String operateType);
public abstract void operateAdd(RequestBean requestBean, ResponseBean responseBean, String operateType);
public abstract void operateDelete(RequestBean requestBean, ResponseBean responseBean, String operateType);
public abstract void operateOther(RequestBean requestBean, ResponseBean responseBean, String operateType); }
|
Service代码优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| protected void doAction(RequestBean requestBean, ResponseBean responseBean) throws Exception { new TemplateService(){ @Override public void operateModify(RequestBean requestBean, ResponseBean responseBean, String operateType) {
} @Override public void operateQuery(RequestBean requestBean, ResponseBean responseBean, String operateType) { queryOrganl(requestBean, responseBean); } @Override public void operateAdd(RequestBean requestBean, ResponseBean responseBean, String operateType) {
} @Override public void operateDelete(RequestBean requestBean, ResponseBean responseBean, String operateType) {
} @Override public void operateOther(RequestBean requestBean, ResponseBean responseBean, String operateType) {
} }.operate(requestBean, responseBean); }
|
这次的代码优化其实有点强行使用设计模式的意思,但是却也是对设计模式的一次应用,加强了对其的理解