构造模式+责任链模式实现链式调用(可以用于参数校验)、涉及值传递和地址传递
参考:https://zhuanlan.zhihu.com/p/553917078?utm_id=0
一、责任链模式
责任链模式(Chain of Responsibility Pattern)是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止。属于行为型模式。
二、责任链模式的优缺点
1、优点
减少大量ifelse;
逻辑清晰明了,添加删除节点、改变节点顺序方便快捷;
请求与处理解耦;
请求处理者只需关注自己感兴趣的请求,对于不感兴趣的请求,直接转发给下一级节点对象;
易于扩展新的请求处理类,符合开闭原则;
2、缺点
责任链太长或处理时间过长,会影响整体性能。
如果需要判断的东西较多,容易造成类保证;
如果每个判断逻辑较简单,可能会造成一个类只做一个小小的数值判断,哈哈;
如果节点对象存在循环链接,可能会造成死循环;
三、实践
传统方法
@Data
public class Programmer {
// 姓名
private String name;
// 项目
private String project;
// 模块
private String module;
// 进度
private double schedule;
// 计划完成时间
private Date completePlanTime;
// 详细信息
private String info;
}
public class Check {
public boolean programmerCheck(Programmer programmer){
if(!"公众号".equals(programmer.getProject())){
return false;
}
if(!"哪吒编程".equals(programmer.getName())){
return false;
}
if(!programmer.getInfo().equals("公众号哪吒编程,定期分享Java干货,还有不定期的送书活动,包邮到你家,哈哈")){
return false;
}
return true;
}
}
通过责任链模式重构代码
1、链路抽象类定义
这部分是责任链模式的核心代码,重点在于通过next获取下一个节点。
定义一个抽象方法doHandler供子类去实现,实现不同的业务逻辑
public abstract class Handler<T> {
protected Handler next;
private void next(Handler next) {
this.next = next;
}
public abstract boolean doHandler(Programmer programmer);
public static class Builder<T> {
private Handler<T> head;
private Handler<T> tail;
public Builder<T> addHandler(Handler handler) {
if (this.head == null) {
this.head = this.tail = handler;
return this;
}
this.tail.next(handler);
this.tail = handler;
return this;
}
public Handler<T> build() {
return this.head;
}
}
}
(1)项目名称检验
/**
* 校验项目名称
*/
public class ProjectHandler extends Handler {
@Override
public boolean doHandler(Programmer programmer) {
if(!"公众号".equals(programmer.getProject())){
return false;
}
if(null == next){
return true;
}
return next.doHandler(programmer);
}
}
校验名字
/**
* 校验名字
*/
public class NameHandler extends Handler {
@Override
public boolean doHandler(Programmer programmer) {
if(!"哪吒编程".equals(programmer.getName())){
return false;
}
if(null == next){
return true;
}
return next.doHandler(programmer);
}
}
校验活动细节
/**
* 校验活动细节
*/
public class InfoHandler extends Handler {
@Override
public boolean doHandler(Programmer programmer) {
if(!programmer.getInfo().contains("扫描文末二维码,关注公众号哪吒编程,定期分享Java干货,还有不定期的送书活动,包邮到你家")){
return false;
}
if(null == next){
return true;
}
return next.doHandler(programmer);
}
}
测试
核心代码流程:
调用流程:
(1)new Hadnler.Builder() 构建Builder类对象
(2)addHandler(new ProjectHandler()) 此时this.head为空。this.head 和this.tail的地址指向 new ProjectHandler()的地址
(3)addHandler(new NameHandler()) 此时的this.head不为空,走下面,this.tail.next指向NameHandler。因为(2)的this.head = this.tail,此时的是引用传递,传递的是内存地址。所以内存地址的next为NameHandler,所以this.head的next为NamHandler。然后this.tail的地址指向NameHandler的地址
(4)addHandler(new InfoHandler())此时this.tail指向NameHandler。他的next指向InfoHandler,所以NameHandler的next指向InfoHandler。然后将他指向InfoHandler
(5)build 获得this.head,然后doHandler()处理,里面的next.doHandler调用NameHandler处理,依次.....
补充:值传递和引用传递
在Java中,所有的基本数据类型(如int、float等)都是通过值传递来传递参数的,而对象引用也是通过值传递来传递的。
值传递是指将变量或者参数的值复制一份,然后传递给函数或者方法。这意味着在函数或者方法内部对参数进行修改,不会影响到原始变量的值。当我们传递一个基本数据类型时,实际上是传递了它的副本。例如:
public class Test1 {
public static void main(String[] args) {
//测试值传递还是引用传递
int i = 3;
System.out.println("i的值为:"+i); //输出3
}
public void change(int a){
a = 10;
}
}
地址传递是指将对象引用的地址复制一份,然后传递给函数或者方法。这里需要注意的是,在Java中,对象本身并没有直接传递,而是传递了对象的引用。这意味着在函数或者方法内部对对象的修改,会影响到原始对象的状态。例如:
public class Test1 {
public static void main(String[] args) {
//测试值传递还是引用传递
People project = new People();
project.name = "tom";
System.out.println("没转变前为:"+project.name); //输出tom
change(project);
System.out.println("转变后为:"+project.name); //输出jerry
}
public static void change(People a){
a.name = "jerry";
}
public static class People{
private String name;
}
}
在内存分析方面,基本数据类型的值存储在栈内存中,而对象引用存储在栈内存中,而对象本身存储在堆内存中。当一个方法被调用时,它会创建一个新的栈帧来保存方法的局部变量和参数。在值传递中,通过复制值的方式将数据从一个栈帧传递到另一个栈帧。在地址传递中,虽然引用的副本被传递,但是它们仍然指向相同的对象,因此对于对象的修改会影响到原始对象。
总结起来,Java中的值传递是指通过复制值的方式传递参数,而地址传递是指通过复制对象引用的地址来传递参数。对于基本数据类型,值传递不会影响原始值;而对于对象引用,地址传递会影响原始对象的状态。
本文作者:spiderMan1-1
本文链接:https://www.cnblogs.com/cgy1995/p/17533614.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步