Java的模板设计模式

Posted 我是程序汪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的模板设计模式相关的知识,希望对你有一定的参考价值。



设计模式程序员面试的时候一般都会问到,回答好了绝对加分

下面我们具体看下,最下方有源码



理论




java中设计模式【模板设计模式】,大家精力主要看后面的例子案例,理论回头在看也行。

1. 模板设计模式在书中定义:

定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。

通俗点的理解就是 :完成一件事情,有固定的数个步骤,但是每个步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。

关键字“骨架”和“肉”,喜欢看字少的开发,看这行。【我理解的理论】

模板模式玩的就是“骨肉分离”,哈哈好惨啊。

学习目标



  • 会在Spring项目中运用模板模式

  • 能看懂框架中模板模式

Spring代码例子



java后端的软件开发工程师们,例子来了

注意本例子比你书本的例子难点点,加了些“作料”【泛型和回调函数】

模板设计模式的核心类就这么多,现在一个个分析下,最后老规矩运行看效果


先回调接口

Java的模板设计模式


默认回调实现

泛型不懂的,不影响看逻辑

Java的模板设计模式


模板方法的接口,注意这里有"作料"泛型方法

Java的模板设计模式


最核心的类,模板类【我喜欢叫他骨架类】,业务的共性逻辑封装好了,后续不用天天改啦

异常类我就不细说了,简单就异常码、描述2个参数。

BaseBizResult也简单就封装了下返回结果

Java的模板设计模式


这是client类,具体实现逻辑的地方

具体长“肉”的地方,回调函数非常的妙

Java的模板设计模式


Java的模板设计模式


spring配置

client注入下


运行效果

java软件开发,controller模拟调用下【我真的跑起来了】




总结




  • 用回调函数是解决模板模式子类非常多的缺点

  • 代码复用就是模板模式的优点,符合“开闭原则”

  • 看懂骨架在哪里,肉又在哪里,基本能理解模板模式的,觉得我写的不好可以去看看Spring里的事务模板源码


具体源码


public interface CommonBizCallback<T> { /** 前置校验 */ void beforeCheck(); /*** 操作逻辑**/ T doAction(); /*** 后置操作*/ void afterAction(T t); /**finally操作*/ void finallyAction(T t);}
public abstract class AbstractDefaultBizCallback<T> implements CommonBizCallback<T> { @Override public void beforeCheck() { } @Override public void afterAction(T t) { } @Override public void finallyAction(T t) { }}
public interface CommonBizOperations { <T> BaseBizResult<T> execute(CommonBizCallback<T> callback);}

public class CommonBizTemplate implements CommonBizOperations { @Override public <T> BaseBizResult<T> execute(CommonBizCallback<T> callback) { T t=null; try { callback.beforeCheck(); t=callback.doAction(); callback.afterAction(t); return buildSuccedResult(t); } catch (BizRuntimeException e) { return buildErrorResult(e.getErrorCode(),e.getErrorMsg()); }catch (Exception e){ return buildErrorResult("911","未知异常"); }finally { callback.finallyAction(t); } } static <T> BaseBizResult<T> buildSuccedResult(T data){ return new BaseBizResult(data); } static BaseBizResult buildErrorResult(String errorCode, String errorMsg){ return new BaseBizResult(errorCode,errorMsg); }
}



public class TemplateBizService {
public BaseBizResult<String> query(String bizId){

//可以spring set方式注入 或 new CommonBizTemplate commonMethodTemplate=new CommonBizTemplate(); BaseBizResult<String> result= commonMethodTemplate.execute( new AbstractDefaultBizCallback<String>() { /*** 前置入参验证*/ @Override public void beforeCheck() { if(StringUtils.isBlank(bizId)){ throw new BizRuntimeException("001","入参id值为空"); } if(StringUtils.equals("a",bizId)){ throw new BizRuntimeException("002","入参id值不能是a"); } } /**操作逻辑* @return */ @Override public String doAction() { //具体业务逻辑层返回 return "业务数据"; } /*** 后置处理 */ @Override public void afterAction(String o) { if(StringUtils.equals(o,"成功返回业务数据")){ System.out.println("记录日志log....."); } }
}); System.out.println(result.getData()); return result; }}


public class BizRuntimeException extends RuntimeException { //建议用异常码枚举 private String errorCode; private String errorMsg;
public BizRuntimeException(String errorCode,String errorMsg) { super(errorMsg); this.errorCode = errorCode; this.errorMsg = errorMsg; }
public String getErrorCode() { return errorCode; }
public void setErrorCode(String errorCode) { this.errorCode = errorCode; }
public String getErrorMsg() { return errorMsg; }
public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; }}

public class BaseBizResult<T> { public BaseBizResult(String errorCode, String errorMsg){ super(); this.succeed=false; this.errorCode=errorCode; this.errorMsg=errorMsg; }
public BaseBizResult(T data) { super(); this.succeed = true; this.data = data; }
private boolean succeed;
private String errorCode;
private String errorMsg;
private T data;
public boolean isSucceed() { return succeed; }
public void setSucceed(boolean succeed) { this.succeed = succeed; }
public String getErrorCode() { return errorCode; }
public void setErrorCode(String errorCode) { this.errorCode = errorCode; }
public String getErrorMsg() { return errorMsg; }
public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; }
public T getData() { return data; }
public void setData(T data) { this.data = data; }}





注意需要面试视频的 回复 001 或002 或 003 等等 3位数字自增的


程序汪往期 精彩回顾








    (目录列的比较全)











以上是关于Java的模板设计模式的主要内容,如果未能解决你的问题,请参考以下文章

如何在导航抽屉活动模板中的片段之间传递字符串变量

VSCode自定义代码片段2——.vue文件的模板

VSCode自定义代码片段1——vue主模板

VSCode自定义代码片段(vue主模板)

VSCode创建自定义用户片段

Eclipse 中的通用代码片段或模板