首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

设计模式之责任链模式

编程知识
2024年08月22日 17:44

责任链模式是面向对象的23种设计模式中的一种,属于行为模式范围。
责任链模式(Chain of Responsibility),
见名知意:就是每一个处理请求的处理器组合成一个链表,链表中的每个节点(执行器)都有机会处理发送的请求。

大致的结构是这个样子:

 


举一个简单的例子:
某公司有一名新员工要入职,则入职过程大致分为三步:
1、签订劳动合同
2、员工信息入库
3、下发工卡
我们按照责任链模式的思路来设计这块业务:

类图如下:

代码如下:

处理器接口

1 package com.example.demo.learn.pattern.behavior.responsibilitychain;
2 
3 public interface IHandler {
4     boolean handle(Employee employee);
5 }

合同处理器

 1 package com.example.demo.learn.pattern.behavior.responsibilitychain;
 2 
 3 /**
 4  * @discription
 5  */
 6 public class CardHandler implements IHandler{
 7     @Override
 8     public boolean handle(Employee employee) {
 9         System.out.println("制作工牌:工号"+employee.getId()+" 姓名:"+employee.getName());
10         return true;
11     }
12 }

协议处理器

 1 package com.example.demo.learn.pattern.behavior.responsibilitychain;
 2 
 3 /**
 4  * @discription
 5  */
 6 public class ContractHandler implements IHandler {
 7     @Override
 8     public boolean handle(Employee employee) {
 9         System.out.println("签订合同:" + employee);
10         return true;
11     }
12 }

系统流程处理器

 1 package com.example.demo.learn.pattern.behavior.responsibilitychain;
 2 
 3 import java.util.Date;
 4 
 5 /**
 6  * @discription
 7  */
 8 public class SystemHandler implements IHandler {
 9     @Override
10     public boolean handle(Employee employee) {
11         long id = new Date().getTime();
12         employee.setId(id);
13         System.out.println("员工信息登入到系统中: " + employee);
14         return true;
15     }
16 }

员工类:业务实体

 1 package com.example.demo.learn.pattern.behavior.responsibilitychain;
 2 
 3 import lombok.Data;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Data
 9 public class Employee {
10     private Long id;
11     private String name;
12 }

主类:责任链的编排和请求调用

 1 package com.example.demo.learn.pattern.behavior.responsibilitychain;
 2 
 3 /**
 4  * @discription
 5  */
 6 public class PatternMain {
 7     public static void main(String[] args) {
 8         ContractHandler contractHandler = new ContractHandler();
 9         SystemHandler systemHandler = new SystemHandler();
10         CardHandler cardHandler = new CardHandler();
11 
12 
13         EntryChain entry = new EntryChain(contractHandler, systemHandler, cardHandler);
14         String name = "小z";
15         boolean result = entry.process(name);
16         if (result) {
17             System.out.println(name + "的入职流程已经处理完");
18         }
19     }
20 }

执行效果如下:

Connected to the target VM, address: '127.0.0.1:63269', transport: 'socket'
签订合同:Employee(id=null, name=小z)
员工信息入库: Employee(id=1724316937102, name=小z)
制作工牌:工号1724316937102 姓名:小z
小z的入职流程已经全部处理完
Disconnected from the target VM, address: '127.0.0.1:63269', transport: 'socket'

来具体说下设计的核心思路:

首先我们需要定义好一个接口,这个接口规范每一个执行器(责任链节点)的执行方法。在本例中就是IHandler接口。
接着我们定义3个实现类(也就是所谓的执行器,即责任链的节点),(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )每个执行器中实现接口的方法,编写当前执行器要做的事。
最后我们需要一个链表来编排当前各个执行器的执行顺序。
当我们将请求下发,系统就可以按照责任链编排的顺序,依次执行了。
有些文章也这样定义:
抽象接口---->抽象处理器(Handler)角色
具体执行器实现---->具体处理者(ConcreteHandler)角色

责任链模式一般应用在:
1、流程编排(如电子流工单处理)
2、资源的使用(依次申请资源--->使用资源--->释放资源)
3、日志记录、权限过滤、请求预处理 (如在aop切面编程执行顺序的编排)

那么为啥要搞责任链模式呢?
我们直接从头到尾写一套流程不就行了么,这样还比较直接,易懂。
如果是简单的使用,那么肯定是可以的,但是如果要是业务流程复杂,又经常变动,以满足开闭原则为初衷,则从头到尾写一套流程就很难维护了。
所以我们可以将各个执行节点(执行器)为对象,按照具体场景,随意的调整顺序,随意的增加新的场景。从这个角度看,是不是逐渐就有了一点面向对象的意思。

设计模式除了举得这个简单的例子外,还有很多的变形:
1、有些场景将责任链的节点,保存在每一个责任链节点的next引用处,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )从而形成一个逻辑上的单链表结构,而不是依赖某一个list来保存。
2、责任链模式既可以从中途结束返回,也可以依次的每个节点都执行,这个没有强制的约束。
3、责任链模式是一个整体的设计思路,并不是某几个固定方法,比如我们的OA流程,就是一个大的流程,可能跨多个服务,并不是某几个方法简单编排一下就可以的。
那么我们应该怎么掌握呢?个人觉得设计模式本来就是一个设计思路,没必要条条框框,按部就班的来。要根据核心思路,以实际情况为场景,来灵活的实现和使用。

From:https://www.cnblogs.com/jilodream/p/18374509
本文地址: http://www.shuzixingkong.net/article/1348
0评论
提交 加载更多评论
其他文章 国产化适配——银河麒麟V10(1)
前言 为响应国家“信创”建设,公司最近在搞国产化适配,我刚好负责这搞一部分,做个记录吧。 主要包括三块:国产服务器操作系统银河麒麟V10,国产数据库人大金仓kingbase,中间件Tongweb。 这一期记录银河麒麟适配中遇到的一些问题。 系统版本:Kylin Linux Advanced Serv
Webpack 核心流程
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。 本文作者:霜序 三个阶段 初始化阶段 初始化参数:从配置文件、配置对象、shell 参数中读取,与默认的配置参数结合得出最后的参数。 创建编译器对象:通过上一步得到的参
Webpack 核心流程 Webpack 核心流程 Webpack 核心流程
AntSK:在无网络环境中构建你的本地AI知识库的终极指南
亲爱的读者朋友们,我是许泽宇,今天我将深入探讨一个引人注目的开源工具——AntSK。这个工具让您在没有互联网连接的情况下,仍然能够进行人工智能知识库的对话和查询。想象一下,即使身处无网络环境中,您也可以轻松与AI进行愉快的交流,这无疑是非常振奋人心的! 项目地址 您可以在GitHub找到这个项目。
AntSK:在无网络环境中构建你的本地AI知识库的终极指南 AntSK:在无网络环境中构建你的本地AI知识库的终极指南 AntSK:在无网络环境中构建你的本地AI知识库的终极指南
manim边学边做--直线类
直线是最常用的二维结构,也是构造其他二维图形的基础。manim中针对线性结构提供了很多模块,本篇主要介绍常用的几个直线类的模块。 Line:通用直线 DashedLine:各种类型的虚线 TangentLine:根据已有的几何体,绘制它的切线 LabeledLine:带有标签的直线 其中,Dashe
manim边学边做--直线类 manim边学边做--直线类 manim边学边做--直线类
[学习笔记]在不同项目中切换Node.js版本
@目录使用 Node Version Manager (NVM)安装 NVM使用 NVM 安装和切换 Node.js 版本为项目指定 Node.js 版本使用环境变量指定 Node.js安装多个版本的 Node.js设置环境变量验证配置使用 npm 脚本切换 在开发中,可能会遇到不同的Vue项目需要
[学习笔记]在不同项目中切换Node.js版本 [学习笔记]在不同项目中切换Node.js版本 [学习笔记]在不同项目中切换Node.js版本
Linux基础优化与常用软件包说明
1.安装常用工具 1.1CentOS(7) 1.1.1 是否联网 ping qq.com 1.1.2 配置yum源(安装软件的软件仓库) 默认情况下yum下载软件的时候是从随机地址下载。 配置yum从国内下载(仅执行即可),修改yum配置指定统一下载地址(阿里云). 修改yum下载软件的地址,改为阿
逆向WeChat (五)
mmmojo,wmpfmojo。本篇逆向mojoIPC。如何从mojo core的MojoHandle找出binding层的Remote跟Receiver,并使用。包括mmmojo.dll, wmpf_host_export.dll。
逆向WeChat (五) 逆向WeChat (五) 逆向WeChat (五)
Terraform中的for_each和count
通过Terraform创建云主机时,在某些业务场景下,一个机器需要挂载多个云盘,一般云厂商都是单独创建云主机和云硬盘然后通过attachment的资源去挂载,因此我们的模板大致如下: resource "tencentcloud_instance" "basic&quo
Terraform中的for_each和count