查看原文
其他

Java的模板设计模式

我是程序汪 我是程序汪 2021-09-08



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

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



理论




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

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

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

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

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

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

学习目标



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

  • 能看懂框架中模板模式

Spring代码例子



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

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

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


先回调接口


默认回调实现

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


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


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

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

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


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

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



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位数字自增的

B站面试视频答案在公众号文章上,希望帮到大家


程序汪往期精彩回顾

面试银行经验月薪要求1万8千java程序员,这次真的通过了


面试造火箭,入职拧螺丝!一个JAVA面试官的心声


乐观锁


悲观锁


目录:我把精华文章都整理出来了    (目录列的比较全)


面试造火箭,入职拧螺丝!一个JAVA面试官的心声


程序汪面试题java篇20190801


log4j


帮公司面试1万到1.5万薪资的Java程序员,来看看我问什么


程序员怎么接私活赚钱


程序员搞自媒体赚钱

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存