建议使用以下浏览器,以获得最佳体验。 ie 9.0 以上版本 chrome 31 谷歌浏览器 firefox 30 火狐浏览器
温馨提示

抱歉,您需设置社区昵称后才能参与社区互动!

前往修改
我再想想
选择版块
鲲鹏论坛 主题:10039帖子:283718

【新手课堂】

java序列化对象与非序列化对象

6 天前 117
## 责任链模式是什么 责任链模式是一种行为型设计模式,也就是重点是处理数据,假设我们有一份数据,需要经过很多个节点处理,那么就会是以下这个样子: 一个节点处理完之后,交给下一个节点,不知道大家有没有使用过审批流,当我们提完一个审批单后,你的`leader`审批,leader审批通过之后就是总监批,总监后面可能是高级总监,或者`cto`,或者`hr`。他们在同一个链条上,倘若你的`leader`没有审批完,后面的节点是不可能收到信息的。如果你的`leader`拒绝了你的申请,那数据也不会到达后面的审批节点。 如果你接触过前端,js 中点击某个 `div` 的时候会产生冒泡事件,也就是点击下面的`a`, `a` 在`b`里面,`b`在`c`里面, `a`-> `b` -> `c` 会依次收到点击事件: 再举个例子,在 `springmvc`中,我们有时候会定义一些拦截器,对请求进行预处理,也就是请求过来的时候,会依次经历拦截器,通过拦截器之后才会进入我们的处理业务逻辑代码。 之前,在做人员管理的时候,有涉及到人员离职情况的处理流程,要交接工作,解除权限,禁用账号等等,这整个处理流程就很适合使用责任链来处理。当然,自动处理流程是会出错的,保存每一个阶段的状态,针对出错的场景,可以手动去从断开责任链的地方接着执行。这整个流程的框架就是应用了责任链,但是根据实际场景也添加了不少其他的东西。 ## 两点疑问 1. 责任链的每一个节点是不是一定包含下一个节点的引用? 答:不一定,要么把所有责任节点放在一个`list`里面,依次处理;要么每个节点包含下一个责任节点的引用, 1. 责任链到底是不允许中断还是不允许中断? 答:两种都可以,不拘泥于细节,可以根据自己的场景使用。 ## 责任链模式中的角色 责任链一般有以下的角色: - `client`(客户端):调用责任链处理器的处理方法,或者在第一个链对象中调用`handle`方法。 - `handler`(处理器):抽象类,提供给实际处理器继承然后实现`handle`方法,处理请求 - `concretehandler`(具体处理器):实现`handler`的类,同时实现`handle`方法,负责处理业务逻辑类,不同业务模块有不同的`concretehandler`。 - `handlerchain`:负责组合责任链的所有节点以及流程(如果节点包含下一个节点的引用,那么`handlerchain`可以不存在) ## 审批链的实现 下面我们分别来实现不同的写法,假设现在有一个场景,秦怀入职了一家公司,哼哧哼哧干了一年,但是一直没调薪,又过了一年,总得加薪了吧,不加就要提桶跑路了,于是秦怀大胆去内部系统提了一个申请单:【加薪申请】 ### 不中断模式 先演示不中断模式,得先弄个申请单的实体,里面包含了申请单的名字和申请人: ```java public class requisition { // 名称 public string name; // 申请人 public string applicant; public requisition(string name, string applicant) { this.name = name; this.applicant = applicant; } } ``` 责任链中的每个责任节点,也就是处理器,可以抽象成为一个接口: ```java public interface handler { // 处理申请单 void process(requisition requisition); } ``` 我们依次实现了三个不同的责任节点,分别代表`leader`,总监,`hr`审批: ```java public class managerhandler implements handler { @override public void process(requisition requisition) { system.out.println(string.format("manager 审批来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); } } public class directorhandler implements handler{ @override public void process(requisition requisition) { system.out.println(string.format("director 审批来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); } } public class hrhandler implements handler{ @override public void process(requisition requisition) { system.out.println(string.format("hr 审批来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); } } ``` 责任节点都有了,我们需要用一个责任链把它们组合起来: ```java public class handlerchain { list handlers = new arraylist<>(); public void addhandler(handler handler){ handlers.add(handler); } public void handle(requisition requisition){ for(handler handler:handlers){ handler.process(requisition); } system.out.println(string.format("来自[%s]的申请单[%s]审批完成", requisition.applicant, requisition.name)); } } ``` 客户端测试类: ```java public class clienttest { public static void main(string[] args) { handlerchain handlerchain = new handlerchain(); handlerchain.addhandler(new managerhandler()); handlerchain.addhandler(new directorhandler()); handlerchain.addhandler(new hrhandler()); handlerchain.handle(new requisition("加薪申请","秦怀")); } } ``` 运行结果: ```java manager 审批来自[秦怀]的申请单[加薪申请]... director 审批来自[秦怀]的申请单[加薪申请]... hr 审批来自[秦怀]的申请单[加薪申请]... 来自[秦怀]的申请单[加薪申请]审批完成 ``` 从结果上来看,申请单确实经历过了每一个节点,形成了一条链条,这就是责任链的核心思想。每个节点拿到的都是同一个数据,同一个申请单。 ### 中断模式 秦怀加薪的想法很美好,但是现实很骨感,上面的审批流程一路畅通,但是万一 hr 想拒绝掉这个申请单了,上面的代码并没有赋予她这种能力,因此,代码得改!(hr 内心:我就要这个功能,明天上线)。 既然是支持中断,也就是支持任何一个节点审批不通过就直接返回,不会再走到下一个节点,先给抽象的处理节点方法加上返回值: ```java public interface handler { // 处理申请单 boolean process(requisition requisition); } ``` 三个处理节点也同步修改: ```java public class managerhandler implements handler { @override public boolean process(requisition requisition) { system.out.println(string.format("manager 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class directorhandler implements handler{ @override public boolean process(requisition requisition) { system.out.println(string.format("director 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class hrhandler implements handler{ @override public boolean process(requisition requisition) { system.out.println(string.format("hr 审批不通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return false; } } ``` 处理链调整: ```java public class handlerchain { list handlers = new arraylist<>(); public void addhandler(handler handler) { handlers.add(handler); } public void handle(requisition requisition) { for (handler handler : handlers) { if (!handler.process(requisition)) { system.out.println(string.format("来自[%s]的申请单[%s]审批不通过", requisition.applicant, requisition.name)); return; } } system.out.println(string.format("来自[%s]的申请单[%s]审批完成", requisition.applicant, requisition.name)); } } ``` 修改完成之后的结果: ```java manager 审批通过来自[秦怀]的申请单[加薪申请]... director 审批通过来自[秦怀]的申请单[加薪申请]... hr 审批不通过来自[秦怀]的申请单[加薪申请]... 来自[秦怀]的申请单[加薪申请]审批不通过 ``` 秦怀哭了,加薪的审批被 hr 拒绝了。虽然被拒绝了,但是秦怀也感受到了可以中断的责任链模式,这种写法在处理请求的时候也比较常见,因为我们不希望不合法的请求到正常的处理逻辑中。 ### 包含下一个节点的引用 前面说过,**在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。**上面的写法都是不包含下一个节点引用的写法。下面我们实践一下,如何使用引用写法完成责任链。 改造`handler`接口为抽象类: ```java public abstract class handler { private handler nexthandler; public void setnexthandler(handler handler) { this.nexthandler = handler; } // 处理申请单 protected abstract boolean process(requisition requisition); // 暴露方法 public boolean handle(requisition requisition) { boolean result = process(requisition); if (result) { if (nexthandler != null) { return nexthandler.handle(requisition); } else { return true; } } return false; } } ``` 三个实现类不变: ```java public class managerhandler extends handler{ @override boolean process(requisition requisition) { system.out.println(string.format( "manager 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class directorhandler extends handler { @override public boolean process(requisition requisition) { system.out.println(string.format( "director 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class hrhandler extends handler{ @override public boolean process(requisition requisition) { system.out.println(string.format("hr 审批不通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return false; } } ``` 测试方法,构造嵌套引用: ```java public class clienttest { public static void main(string[] args) { hrhandler hrhandler = new hrhandler(); directorhandler directorhandler = new directorhandler(); directorhandler.setnexthandler(hrhandler); managerhandler managerhandler = new managerhandler(); managerhandler.setnexthandler(directorhandler); managerhandler.handle(new requisition("加薪申请","秦怀")); } } ``` 可以看到运行结果也是一样: ```java manager 审批通过来自[秦怀]的申请单[加薪申请]... director 审批通过来自[秦怀]的申请单[加薪申请]... hr 审批不通过来自[秦怀]的申请单[加薪申请]... ``` ### 拓展一下 其实责任链配合上`spring`更加好用,主要有两点: 1、可以使用注入,自动识别该接口的所有实现类。 ```java @autowire public list handlers; ``` 2、可以使用`@order`注解,让接口实现类按照顺序执行。 ```java @order(1) public class hrhandler extends handler{ ... } ``` ### 源码中的应用 - `mybatis` 中的 `plugin` 机制使用了责任链模式,配置各种官方或者自定义的 `plugin`,与 `filter` 类似,可以在执行 `sql` 语句的时候执行一些操作。 - `spring`中使用责任链模式来管理`adviser`。 比如`mybatis`中可以添加若干的插件,比如`pagehelper`,多个插件对对象的包装采用的动态代理来实现,多层代理。 ```java //责任链插件 public class interceptorchain { private final list interceptors = new arraylist<>(); // 生成代理对象 public object pluginall(object target) { for (interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } //一层一层的拦截器 public void addinterceptor(interceptor interceptor) { interceptors.add(interceptor); } public list getinterceptors() { return collections.unmodifiablelist(interceptors); } } ``` ## 总结 责任链模式的优点: - 降低对象直接的耦合度,对象会自动传递到下一个责任节点,不管是引用方式,还是非引用方式。 - 增强拓展性,如果需要添加新的责任节点,也比较方便,实现特定的接口即可。 - 责任节点的顺序可控,可以指定一个顺序属性,排序即可。 - 每个责任节点职责专一,只处理自己的任务,符合类的单一职责原则。 责任链的缺点: - 如果责任链比较长,性能会受影响。 - 责任链可能会中途断掉,请求不一定会被接收。 责任链一般是在流程化的处理中,多个节点处理同一份数据,依次传递,可能有顺序要求,也可能没有,处理器的能力抽象成接口,方便拓展。

回复7

0 0
2022/6/1 12:50

感谢分享

0 0
2022/6/6 13:58

感谢分享

0 0
2022/6/6 14:12

感谢分享

0 0
2022/6/6 14:19

123

0 0
2022/6/6 21:33

感谢分享

0 0
2022/6/6 21:52

感谢分享

0 0
2022/6/6 22:12

感谢分享

上划加载中
直达楼层
全部回复
正序浏览
标签
您还可以添加5个标签
  • 没有搜索到和“关键字”相关的标签
  • 云产品
  • 4008云顶国际网站的解决方案
  • 技术领域
  • 通用技术
  • 平台功能
取消

java序列化对象与非序列化对象-4008云顶国际网站

您已采纳当前回复为最佳回复

乌龟哥哥

发帖: 79粉丝: 21

发表于2022年05月31日 23:05:49 117 7
[新手课堂] java序列化对象与非序列化对象
## 责任链模式是什么 责任链模式是一种行为型设计模式,也就是重点是处理数据,假设我们有一份数据,需要经过很多个节点处理,那么就会是以下这个样子: 一个节点处理完之后,交给下一个节点,不知道大家有没有使用过审批流,当我们提完一个审批单后,你的`leader`审批,leader审批通过之后就是总监批,总监后面可能是高级总监,或者`cto`,或者`hr`。他们在同一个链条上,倘若你的`leader`没有审批完,后面的节点是不可能收到信息的。如果你的`leader`拒绝了你的申请,那数据也不会到达后面的审批节点。 如果你接触过前端,js 中点击某个 `div` 的时候会产生冒泡事件,也就是点击下面的`a`, `a` 在`b`里面,`b`在`c`里面, `a`-> `b` -> `c` 会依次收到点击事件: 再举个例子,在 `springmvc`中,我们有时候会定义一些拦截器,对请求进行预处理,也就是请求过来的时候,会依次经历拦截器,通过拦截器之后才会进入我们的处理业务逻辑代码。 之前,在做人员管理的时候,有涉及到人员离职情况的处理流程,要交接工作,解除权限,禁用账号等等,这整个处理流程就很适合使用责任链来处理。当然,自动处理流程是会出错的,保存每一个阶段的状态,针对出错的场景,可以手动去从断开责任链的地方接着执行。这整个流程的框架就是应用了责任链,但是根据实际场景也添加了不少其他的东西。 ## 两点疑问 1. 责任链的每一个节点是不是一定包含下一个节点的引用? 答:不一定,要么把所有责任节点放在一个`list`里面,依次处理;要么每个节点包含下一个责任节点的引用, 1. 责任链到底是不允许中断还是不允许中断? 答:两种都可以,不拘泥于细节,可以根据自己的场景使用。 ## 责任链模式中的角色 责任链一般有以下的角色: - `client`(客户端):调用责任链处理器的处理方法,或者在第一个链对象中调用`handle`方法。 - `handler`(处理器):抽象类,提供给实际处理器继承然后实现`handle`方法,处理请求 - `concretehandler`(具体处理器):实现`handler`的类,同时实现`handle`方法,负责处理业务逻辑类,不同业务模块有不同的`concretehandler`。 - `handlerchain`:负责组合责任链的所有节点以及流程(如果节点包含下一个节点的引用,那么`handlerchain`可以不存在) ## 审批链的实现 下面我们分别来实现不同的写法,假设现在有一个场景,秦怀入职了一家公司,哼哧哼哧干了一年,但是一直没调薪,又过了一年,总得加薪了吧,不加就要提桶跑路了,于是秦怀大胆去内部系统提了一个申请单:【加薪申请】 ### 不中断模式 先演示不中断模式,得先弄个申请单的实体,里面包含了申请单的名字和申请人: ```java public class requisition { // 名称 public string name; // 申请人 public string applicant; public requisition(string name, string applicant) { this.name = name; this.applicant = applicant; } } ``` 责任链中的每个责任节点,也就是处理器,可以抽象成为一个接口: ```java public interface handler { // 处理申请单 void process(requisition requisition); } ``` 我们依次实现了三个不同的责任节点,分别代表`leader`,总监,`hr`审批: ```java public class managerhandler implements handler { @override public void process(requisition requisition) { system.out.println(string.format("manager 审批来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); } } public class directorhandler implements handler{ @override public void process(requisition requisition) { system.out.println(string.format("director 审批来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); } } public class hrhandler implements handler{ @override public void process(requisition requisition) { system.out.println(string.format("hr 审批来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); } } ``` 责任节点都有了,我们需要用一个责任链把它们组合起来: ```java public class handlerchain { list handlers = new arraylist<>(); public void addhandler(handler handler){ handlers.add(handler); } public void handle(requisition requisition){ for(handler handler:handlers){ handler.process(requisition); } system.out.println(string.format("来自[%s]的申请单[%s]审批完成", requisition.applicant, requisition.name)); } } ``` 客户端测试类: ```java public class clienttest { public static void main(string[] args) { handlerchain handlerchain = new handlerchain(); handlerchain.addhandler(new managerhandler()); handlerchain.addhandler(new directorhandler()); handlerchain.addhandler(new hrhandler()); handlerchain.handle(new requisition("加薪申请","秦怀")); } } ``` 运行结果: ```java manager 审批来自[秦怀]的申请单[加薪申请]... director 审批来自[秦怀]的申请单[加薪申请]... hr 审批来自[秦怀]的申请单[加薪申请]... 来自[秦怀]的申请单[加薪申请]审批完成 ``` 从结果上来看,申请单确实经历过了每一个节点,形成了一条链条,这就是责任链的核心思想。每个节点拿到的都是同一个数据,同一个申请单。 ### 中断模式 秦怀加薪的想法很美好,但是现实很骨感,上面的审批流程一路畅通,但是万一 hr 想拒绝掉这个申请单了,上面的代码并没有赋予她这种能力,因此,代码得改!(hr 内心:我就要这个功能,明天上线)。 既然是支持中断,也就是支持任何一个节点审批不通过就直接返回,不会再走到下一个节点,先给抽象的处理节点方法加上返回值: ```java public interface handler { // 处理申请单 boolean process(requisition requisition); } ``` 三个处理节点也同步修改: ```java public class managerhandler implements handler { @override public boolean process(requisition requisition) { system.out.println(string.format("manager 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class directorhandler implements handler{ @override public boolean process(requisition requisition) { system.out.println(string.format("director 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class hrhandler implements handler{ @override public boolean process(requisition requisition) { system.out.println(string.format("hr 审批不通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return false; } } ``` 处理链调整: ```java public class handlerchain { list handlers = new arraylist<>(); public void addhandler(handler handler) { handlers.add(handler); } public void handle(requisition requisition) { for (handler handler : handlers) { if (!handler.process(requisition)) { system.out.println(string.format("来自[%s]的申请单[%s]审批不通过", requisition.applicant, requisition.name)); return; } } system.out.println(string.format("来自[%s]的申请单[%s]审批完成", requisition.applicant, requisition.name)); } } ``` 修改完成之后的结果: ```java manager 审批通过来自[秦怀]的申请单[加薪申请]... director 审批通过来自[秦怀]的申请单[加薪申请]... hr 审批不通过来自[秦怀]的申请单[加薪申请]... 来自[秦怀]的申请单[加薪申请]审批不通过 ``` 秦怀哭了,加薪的审批被 hr 拒绝了。虽然被拒绝了,但是秦怀也感受到了可以中断的责任链模式,这种写法在处理请求的时候也比较常见,因为我们不希望不合法的请求到正常的处理逻辑中。 ### 包含下一个节点的引用 前面说过,**在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。**上面的写法都是不包含下一个节点引用的写法。下面我们实践一下,如何使用引用写法完成责任链。 改造`handler`接口为抽象类: ```java public abstract class handler { private handler nexthandler; public void setnexthandler(handler handler) { this.nexthandler = handler; } // 处理申请单 protected abstract boolean process(requisition requisition); // 暴露方法 public boolean handle(requisition requisition) { boolean result = process(requisition); if (result) { if (nexthandler != null) { return nexthandler.handle(requisition); } else { return true; } } return false; } } ``` 三个实现类不变: ```java public class managerhandler extends handler{ @override boolean process(requisition requisition) { system.out.println(string.format( "manager 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class directorhandler extends handler { @override public boolean process(requisition requisition) { system.out.println(string.format( "director 审批通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return true; } } public class hrhandler extends handler{ @override public boolean process(requisition requisition) { system.out.println(string.format("hr 审批不通过来自[%s]的申请单[%s]...", requisition.applicant, requisition.name)); return false; } } ``` 测试方法,构造嵌套引用: ```java public class clienttest { public static void main(string[] args) { hrhandler hrhandler = new hrhandler(); directorhandler directorhandler = new directorhandler(); directorhandler.setnexthandler(hrhandler); managerhandler managerhandler = new managerhandler(); managerhandler.setnexthandler(directorhandler); managerhandler.handle(new requisition("加薪申请","秦怀")); } } ``` 可以看到运行结果也是一样: ```java manager 审批通过来自[秦怀]的申请单[加薪申请]... director 审批通过来自[秦怀]的申请单[加薪申请]... hr 审批不通过来自[秦怀]的申请单[加薪申请]... ``` ### 拓展一下 其实责任链配合上`spring`更加好用,主要有两点: 1、可以使用注入,自动识别该接口的所有实现类。 ```java @autowire public list handlers; ``` 2、可以使用`@order`注解,让接口实现类按照顺序执行。 ```java @order(1) public class hrhandler extends handler{ ... } ``` ### 源码中的应用 - `mybatis` 中的 `plugin` 机制使用了责任链模式,配置各种官方或者自定义的 `plugin`,与 `filter` 类似,可以在执行 `sql` 语句的时候执行一些操作。 - `spring`中使用责任链模式来管理`adviser`。 比如`mybatis`中可以添加若干的插件,比如`pagehelper`,多个插件对对象的包装采用的动态代理来实现,多层代理。 ```java //责任链插件 public class interceptorchain { private final list interceptors = new arraylist<>(); // 生成代理对象 public object pluginall(object target) { for (interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } //一层一层的拦截器 public void addinterceptor(interceptor interceptor) { interceptors.add(interceptor); } public list getinterceptors() { return collections.unmodifiablelist(interceptors); } } ``` ## 总结 责任链模式的优点: - 降低对象直接的耦合度,对象会自动传递到下一个责任节点,不管是引用方式,还是非引用方式。 - 增强拓展性,如果需要添加新的责任节点,也比较方便,实现特定的接口即可。 - 责任节点的顺序可控,可以指定一个顺序属性,排序即可。 - 每个责任节点职责专一,只处理自己的任务,符合类的单一职责原则。 责任链的缺点: - 如果责任链比较长,性能会受影响。 - 责任链可能会中途断掉,请求不一定会被接收。 责任链一般是在流程化的处理中,多个节点处理同一份数据,依次传递,可能有顺序要求,也可能没有,处理器的能力抽象成接口,方便拓展。

分享文章到朋友圈

分享文章到微博
您已采纳当前回复为最佳回复

发帖: 0粉丝: 0

发表于2022年06月01日 12:50:57

感谢分享

您已采纳当前回复为最佳回复

jack20

发帖: 517粉丝: 227

发表于2022年06月06日 13:58:45

感谢分享

您已采纳当前回复为最佳回复

发帖: 0粉丝: 0

发表于2022年06月06日 14:12:43

感谢分享

您已采纳当前回复为最佳回复

发帖: 0粉丝: 0

发表于2022年06月06日 14:19:47

123

您已采纳当前回复为最佳回复

发帖: 582粉丝: 6

发表于2022年06月06日 21:33:22

感谢分享

您已采纳当前回复为最佳回复

红鲤鱼与绿鲤鱼

发帖: 2粉丝: 2

发表于2022年06月06日 21:52:02

感谢分享

您已采纳当前回复为最佳回复

慕雪

发帖: 2粉丝: 2

发表于2022年06月06日 22:12:08

感谢分享

您需要登录后才可以回帖 | 立即注册

您对问题的回复是否满意?
满意度
非常满意 满意 一般 不满意
我要反馈
0/200
网站地图