当前位置: 首页 > news >正文

行为型设计模式—职责链模式

职责链模式:从名字可以拆分为 职责 和 链。即能为请求创建一条由多个处理器组成的链路,每个处理器各自负责自己的职责,相互之间没有耦合,完成自己任务后请求对象即传递到链路的下一个处理器进行处理。

如果在写好的执行函数里加上部分步骤,导致需要增加若干个if-else,因为整个流程耦合在一起,修改了以后我们就得把整个流程全测一遍。。 而职责链就是把步骤解耦为执行链条,从而消除牵一发而动全身的后果。(链表插入优点是遍历到前节点插入即可,不需要像顺序表一样移动之后所有元素)

在一些核心的业务中,应用职责链模式能够让我们无痛地扩展业务流程的步骤

实现责任链模式的对象最起码需要包含如下特性:

  • 成员属性

    • nextHandler: 下一个等待被调用的对象实例
  • 成员方法

    • SetNext: 把下一个对象的实例绑定到当前对象的nextHandler属性上;
    • Do: 当前对象业务逻辑入口,他是每个处理对象实现自己逻辑的地方;
    • Execute: 负责职责链上请求的处理和传递;它会调用当前对象的DonextHandler不为空则调用nextHandler.Do

SetNextExecute 这两个行为是每个 ConcreteHandler 都一样的,所以这两个可以交给抽象处理类型来实现,每个具体处理对象再继承抽象类型,即可减少重复操作。

以病人去医院看病这个处理流程为例提供一个具体示例。看病的具体流程如下:

挂号—>诊室看病—>收费处缴费—>药房拿药

利用责任链模式,实现这个流程中的每个步骤,且相互间不耦合,还支持向流程中增加步骤。

先实现职责链模式里的公共部分—即模式的接口和抽象类

type PatientHandler interface {Execute(*patient) errorSetNext(PatientHandler) PatientHandlerDo(*patient) error
}
// 充当抽象类型,实现公共方法,抽象方法不实现留给实现类自己实现
type Next struct {nextHandler PatientHandler
}func (n *Next) SetNext(handler PatientHandler) PatientHandler {n.nextHandler = handlerreturn handler
}func (n *Next) Execute(patient *patient) (err error) {// 调用不到外部类型的 Do 方法,所以 Next 不能实现 Do 方法if n.nextHandler != nil {if err = n.nextHandler.Do(patient); err != nil {return}return n.nextHandler.Execute(patient)}return
}

即使Next实现了Do方法,go语言中语法也不能达到在父类方法中调用子类方法的效果—即在例子里面用Next 类型的Execute方法调用不到外部实现类型的Do方法。

定义职责链要处理的请求,实现处理逻辑和请求传递的DoExecute方法的参数都是流程中要处理的请求。这里是医院接诊的流程,所以定义一个患者类作为流程的请求。

//流程中的请求类--患者
type patient struct {Name              stringRegistrationDone  boolDoctorCheckUpDone boolMedicineDone      boolPaymentDone       bool
}

按照挂号—>诊室看病—>收费处缴费—>药房拿药这个流程定义四个步骤的处理类,来分别实现每个环节的逻辑。

// Reception 挂号处处理器
type Reception struct {Next
}func (r *Reception) Do(p *patient) (err error) {if p.RegistrationDone {fmt.Println("Patient registration already done")return}fmt.Println("Reception registering patient")p.RegistrationDone = truereturn
}// Clinic 诊室处理器--用于医生给病人看病
type Clinic struct {Next
}func (d *Clinic) Do(p *patient) (err error) {if p.DoctorCheckUpDone {fmt.Println("Doctor checkup already done")return}fmt.Println("Doctor checking patient")p.DoctorCheckUpDone = truereturn
}// Cashier 收费处处理器
type Cashier struct {Next
}func (c *Cashier) Do(p *patient) (err error) {if p.PaymentDone {fmt.Println("Payment Done")return}fmt.Println("Cashier getting money from patient patient")p.PaymentDone = truereturn
}// Pharmacy 药房处理器
type Pharmacy struct {Next
}func (m *Pharmacy) Do (p *patient) (err error) {if p.MedicineDone {fmt.Println("Medicine already given to patient")return}fmt.Println("Pharmacy giving medicine to patient")p.MedicineDone = truereturn
}

Recepiton接诊挂号这个步骤提供的逻辑没有调用到,再定义StartHandler 类型,它不提供处理实现只是作为第一个Handler向下转发请求

// StartHandler 不做操作,作为第一个Handler向下转发请求
type StartHandler struct {Next
}// Do 空Handler的Do
func (h *StartHandler) Do(c *patient) (err error) {// 空Handler 这里什么也不做 只是载体 do nothing...return
}

这是Go 语法限制,公共方法Exeute并不能像面向对象那样先调用this.Do 再调用this.nextHandler.Do

把处理类串起来执行

func main() {patientHealthHandler := StartHandler{}//patient := &patient{Name: "abc"}// 设置病人看病的链路patientHealthHandler.SetNext(&Reception{}).// 挂号SetNext(&Clinic{}). // 诊室看病SetNext(&Cashier{}). // 收费处交钱SetNext(&Pharmacy{}) // 药房拿药//还可以扩展,比如中间加入化验科化验,图像科拍片等等// 执行上面设置好的业务流程if err := patientHealthHandler.Execute(patient); err != nil {// 异常fmt.Println("Fail | Error:" + err.Error())return}// 成功fmt.Println("Success")
}

职责链也可以设置中止条件,针对例子就是在Execute方法里加判断,一旦满足中止后就不再继续往链路的下级节点传递请求。

这也是职责链跟装饰器模式的一个区别,装饰器模式无法在增强实体的过程中停止,只能执行完整个装饰链路。

针对那些可能未来经常会变的核心业务流程,可以在设计初期就考虑使用职责链来实现,减轻未来流程不停迭代时不好扩展的痛点。

职责链模式与模板模式的区别在于,模板模式的业务流程通常是规定不变的,而职责链模式业务是可拓展的

相关文章:

行为型设计模式—职责链模式

职责链模式:从名字可以拆分为 职责 和 链。即能为请求创建一条由多个处理器组成的链路,每个处理器各自负责自己的职责,相互之间没有耦合,完成自己任务后请求对象即传递到链路的下一个处理器进行处理。 如果在写好的执行函数里加上…...

EndNote快速上手

前言:用EndNote主要就是为了方便管理文章引用的文献,所以本篇就是针对EndNote在文章中引用文献需要的技巧,然后本文用的是EndNoteX9。 EndNote快速上手 创建文献资料库创建文献分组导入文献手动输入文件导入在线搜索 修改文献信息去重文献删除…...

GRE隧道(初级VPN)配置步骤

一、拓朴图: 要求:1、PC1 和 PC2 能访问充当互联网接口地址的ISP环回口地址8.8.8.8 2、PC1 和 PC2 走GRE隧道互通 二、配置步骤: 1、配置IP 2、R1、R2 配置nat,代理内网地址通过G0/0/0口上外网 acl 2000rule permit source a…...

自然语言处理笔记

文章目录 情感词典中文分词单词向量化技术Word2vecGloVefastText 关键词提取算法 情感词典 英文的情感词典有:LIWC, SentiWordNet等 中文的情感词典有:NTUSD, 正文褒贬词典TSING, 知网HowNet等 中文分词 中文分词的工具有:jieba(核心算法是…...

广东省第三届职业技能大赛“网络安全项目”B模块任务书

广东省第三届职业技能大赛“网络安全项目”B模块任务书 PS: 关注鱼影安全第一部分 网络安全事件响应任务 1:应急响应 第二部分 数字取证调查任务 2 :操作系统取证任务 3: 网络数据包分析取证任务 4: 计算机单机取证 第三部分 应用…...

如何利用API接口获取电商平台数据?

作为产品经理,我们需要了解电商平台的数据情况,以便更好地制定产品策略和优化用户体验。而利用API接口获取电商平台数据是一种高效、便捷的方式。本文将从以下几个方面介绍如何利用API接口获取电商平台数据。 一、了解API接口 首先,我们需要…...

C语言天花板——指针(经典题目)

指针我们已经学习的差不多了,今天我来给大家分享几个经典的题目,来让我们相互学习🏎️🏎️🏎️ int main() {int a[4] { 1, 2, 3, 4 };int* ptr1 (int*)(&a 1);int* ptr2 (int*)((int)a 1);printf("%x,%…...

进程上下文的概念和切换简单通俗的解释

进程上下文是进程执行活动全过程的静态描述。我们把已执行过的进程指令和数据在相关寄存器与堆栈中的内容称为进程上文,把正在执行的指令和数据在寄存器与堆栈中的内容称为进程正文,把待执行的指令和数据在寄存器与堆栈中的内容称为进程下文。 实际上li…...

python学习笔记10(选择结构2、循环结构1)

(一)选择结构2 1、if……else……语句 #(1)基本格式 numbereval(input("请输入您的6位中奖号码:")) if number123456:print("恭喜您,中奖了") else:print("未中奖")#&…...

IPv6过渡技术---手动隧道

IPv6隧道 隧道(Tunnel)是一种封装技术。利用一种网络协议来传输另一种网络协议,即利用一种网络传输协议,将其他协议产生的数据报文封装在自身的报文中,然后在网络中传输。 隧道是一个虚拟的点对点的连接。一个Tunnel提供了一条使封装的数据报文能够传输的通路,并且在一个…...

Redis中的Java客户端

一、Jedis Jedis是一个Java实现的Redis客户端连接工具。 Jedis使用非常简单,直接引入依赖。基于默认参数的Jedis连接池,初始化连接池类(使用默认连接池参数)JedisPool,获取一个Jedis连接Jedis jedisjp.getResource()…...

线性代数——行列式相关性质

目录 一、行列式与它的转置列行列式相等 二、对换行列式的两行(列),行列式变号 三、行列式某行(列)有公因子k,则k可以提到行列式外 四、行列式中若两行成比例,则行列式为0 五、行列式的某一行…...

跟着cherno手搓游戏引擎【5】layer(层)、Glad

编写基类层: Layer.h:提供Attach链接、Detach解绑、Update刷新、Event事件、GetName方法 #pragma once #include"YOTO/Core.h" #include"YOTO/Event/Event.h" namespace YOTO {class YOTO_API Layer{public:Layer(const std::string& nam…...

Windows无法登录管理路由器故障排查

问题描述 家里的路由器使用拨号上网,路由器DHCP分发IP的范围是192.168.1.0/24。默认使用192.168.1.1管理路由器。然后拨号上网成功后,修改了私网IP的分发范围:192.168.5.1-192.168.5.10。为了防止有人蹭网,只分配的10个IP地址。修…...

通义灵码 - 免费的阿里云 VS code Jetbrains AI 编码辅助工具

系列文章目录 前言 通义灵码,是阿里云出品的一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力,并针对阿里云 SDK/OpenAPI 的使用…...

山脉数组的峰顶索引

一、题目描述 852. 山脉数组的峰顶索引 符合下列属性的数组 arr 称为 山脉数组 &#xff1a; arr.length > 3存在 i&#xff08;0 < i < arr.length - 1&#xff09;使得&#xff1a; arr[0] < arr[1] < ... arr[i-1] < arr[i] arr[i] > arr[i1] > .…...

openssl3.2 - 官方demo学习 - cms - cms_ver.c

文章目录 openssl3.2 - 官方demo学习 - cms - cms_ver.c概述运行结果笔记END openssl3.2 - 官方demo学习 - cms - cms_ver.c 概述 CMS验签, 将单独签名和联合签名出来的签名文件都试试. 验签成功后, 将签名数据明文写入了文件供查看. 也就是说, 只有验签成功后, 才能看到签名…...

数据结构:堆和堆排序

数据结构&#xff1a;堆和堆排序 文章目录 数据结构&#xff1a;堆和堆排序1.二叉树的存储结构1.顺序结构2.链式结构 2.堆3.堆的实现4.堆排序&#xff08;选择排序中的一类&#xff09;1. 基本思想2.代码实现 1.二叉树的存储结构 1.顺序结构 顺序结构存储就是使用数组来表示一…...

力扣精选算法100题——水果成篮(滑动窗口专题)

本题链接&#x1f449;水果成篮 第一步&#xff1a;了解题意 我就按照实例1来进行对这题的理解。 1代表种类类型&#xff0c;这个数组里面有2个种类类型 ps:种类1和种类2 &#xff0c;只不过种类1是有2个水果&#xff0c;种类2有一个水果&#xff0c;共计3个水果。 本题需要解…...

【提示学习论文六】MaPLe: Multi-modal Prompt Learning论文原理

文章目录 MaPLe: Multi-modal Prompt Learning 多模式提示学习文章介绍动机MaPLe:Multi-modal Prompt Learning 模型结构1、Deep Language Prompting 深度语言提示2、Deep Vision Prompting 深度视觉提示3、Vision Language Prompt Coupling 视觉语言提示耦合提示耦合过程 实验…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...