职责链模式,非常容易被忽视的设计模式之一(设计模式与开发实践 P13)
文章目录
- 现实实例
- 反例
- 优化
- 异步职责链
职责链模式在 C# 中是常见的,他的定义是:使多个对象都有机会处理请求,从而避免发送者和请求者之间的耦合关系,将对象连成一条链并传递该请求,直到有一个对象处理它为止
现实实例
上公交车要把硬币递给后排的售票员(现在应该不常见了)运气好第一个人就是售票员,负责要一直传递直到找到售票员
请求发送者只知道链中的第一个节点,弱化了发送者和接受者之间的强联系,如果不使用职责链模式,我们只能知道谁是售票员,才能把硬币给他
反例
假设你正在开发一个在线购物网站,其中有一个订单处理系统。在该系统中,订单需要经过一系列的验证和处理步骤,包括库存检查、支付验证、优惠券验证和物流处理
如果是一个程序员新手他有可能实现这样的代码,每个步骤都硬编码在里面,难以扩展和优化:
public class OrderProcessor
{public void ProcessOrder(Order order){// 库存检查bool stockAvailable = CheckStock(order);if (!stockAvailable){Console.WriteLine("库存不足");return;}// 支付验证bool paymentValidated = ValidatePayment(order);if (!paymentValidated){Console.WriteLine("支付验证失败");return;}// 优惠券验证bool couponValidated = ValidateCoupon(order);if (!couponValidated){Console.WriteLine("优惠券验证失败");return;}// 物流处理ProcessShipping(order);}private bool CheckStock(Order order){// 检查库存逻辑// ...}private bool ValidatePayment(Order order){// 支付验证逻辑// ...}private bool ValidateCoupon(Order order){// 优惠券验证逻辑// ...}private void ProcessShipping(Order order){// 物流处理逻辑// ...}
}public class Order
{// 订单数据// ...
}
优化
这是使用职责链模式优化的代码,把请求解耦分给不同的 Handler 执行,并通过设置 Next Handler 找到下一个职责任务,这就拆分了不同的执行节点,变得可扩展了
public abstract class OrderHandler
{protected OrderHandler NextHandler;public void SetNextHandler(OrderHandler handler){NextHandler = handler;}public abstract void ProcessOrder(Order order);
}public class StockCheckHandler : OrderHandler
{public override void ProcessOrder(Order order){bool stockAvailable = CheckStock(order);if (!stockAvailable){Console.WriteLine("库存不足");return;}if (NextHandler != null){NextHandler.ProcessOrder(order);}}private bool CheckStock(Order order){// 检查库存逻辑// ...}
}public class PaymentValidationHandler : OrderHandler
{public override void ProcessOrder(Order order){bool paymentValidated = ValidatePayment(order);if (!paymentValidated){Console.WriteLine("支付验证失败");return;}if (NextHandler != null){NextHandler.ProcessOrder(order);}}private bool ValidatePayment(Order order){// 支付验证逻辑// ...}
}public class CouponValidationHandler : OrderHandler
{public override void ProcessOrder(Order order){bool couponValidated = ValidateCoupon(order);if (!couponValidated){Console.WriteLine("优惠券验证失败");return;}if (NextHandler != null){NextHandler.ProcessOrder(order);}}private bool ValidateCoupon(Order order){// 优惠券验证逻辑// ...}
}public class ShippingHandler : OrderHandler
{public override void ProcessOrder(Order order){// 物流处理逻辑// ...}
}// 在客户端代码中构建职责链
public class Client
{public void Main(){OrderHandler stockCheckHandler = new StockCheckHandler();OrderHandler paymentValidationHandler = new PaymentValidationHandler();OrderHandler couponValidationHandler = new CouponValidationHandler();OrderHandler shippingHandler = new ShippingHandler();stockCheckHandler.SetNextHandler(paymentValidationHandler);paymentValidationHandler.SetNextHandler(couponValidationHandler);couponValidationHandler.SetNextHandler(shippingHandler);OrderProcessor orderProcessor = new OrderProcessor(stockCheckHandler);Order order = new Order();orderProcessor.ProcessOrder(order);}
}public class OrderProcessor
{private OrderHandler _orderHandler;public OrderProcessor(OrderHandler orderHandler){_orderHandler = orderHandler;}public void ProcessOrder(Order order){_orderHandler.ProcessOrder(order);}
}public class Order
{// 订单数据// ...
}
异步职责链
每个具体的处理器类都可以异步执行相应的任务,并将结果传递给下一个处理器。通过使用异步职责链模式,将注册过程的不同步骤解耦并异步处理,提高性能和响应速度
public abstract class RegistrationHandler
{protected RegistrationHandler NextHandler;public void SetNextHandler(RegistrationHandler handler){NextHandler = handler;}public abstract Task<bool> ProcessAsync(RegistrationRequest request);
}public class UsernameValidationHandler : RegistrationHandler
{public override async Task<bool> ProcessAsync(RegistrationRequest request){// 验证用户名是否有效await Task.Delay(1000); // 模拟异步操作bool isValid = !string.IsNullOrEmpty(request.Username);Console.WriteLine("Username validation completed");// 将结果传递给下一个处理器if (NextHandler != null){return await NextHandler.ProcessAsync(request) && isValid;}return isValid;}
}public class EmailValidationHandler : RegistrationHandler
{public override async Task<bool> ProcessAsync(RegistrationRequest request){// 验证电子邮件是否有效await Task.Delay(1000); // 模拟异步操作bool isValid = !string.IsNullOrEmpty(request.Email);Console.WriteLine("Email validation completed");// 将结果传递给下一个处理器if (NextHandler != null){return await NextHandler.ProcessAsync(request) && isValid;}return isValid;}
}public class AccountCreationHandler : RegistrationHandler
{public override async Task<bool> ProcessAsync(RegistrationRequest request){// 创建用户账户await Task.Delay(1000); // 模拟异步操作bool isSuccess = true; // 假设账户创建成功Console.WriteLine("Account creation completed");// 将结果传递给下一个处理器if (NextHandler != null){return await NextHandler.ProcessAsync(request) && isSuccess;}return isSuccess;}
}
相关文章:
职责链模式,非常容易被忽视的设计模式之一(设计模式与开发实践 P13)
文章目录 现实实例反例优化异步职责链 职责链模式在 C# 中是常见的,他的定义是:使多个对象都有机会处理请求,从而避免发送者和请求者之间的耦合关系,将对象连成一条链并传递该请求,直到有一个对象处理它为止 现实实例…...
架构师选择题--计算机网络
架构师选择题--计算机网络 22年考题21年考题 22年考题 d http:80 https:httpssl :443 b b pop3是邮件接收协议:110 SMTP是邮件发送协议:25 http:80 A 网络隔离:防火墙(逻辑),网闸(物…...
【图论】Linova and Kingdom—CF1336A
Linova and Kingdom—CF1336A 参考文章 思路 1 1 1 号节点为根节点。很容易想到,工业城市在树的下边,旅游城市在树的上边。具体来说,如果节点 u u u 是工业城市,那么它的子树的所有节点一定都是工业城市;如果节点 u…...
【红日靶场】vulnstack3-完整渗透过程
系列文章目录 【红日靶场】vulnstack1-完整渗透过程 【红日靶场】vulnstack2-完整渗透过程 【红日靶场】vulnstack3-完整渗透过程 文章目录 系列文章目录基本信息环境配置开始渗透信息收集暴力破解漏洞利用绕过内网信息收集尝试上线msf上线msf横向移动msf 传达会话给cs横向到域…...
物联网通信技术课程作业资料(TPUNB技术)
参考内容 TPUNB无线通信技术 - 技象科技 (techphant.cn) 技象科技CTO郑凛:用最好的物联网服务最多的人 | 了不起的创变者_技术_通信_团队 (sohu.com) LPWAN技术融合使用大势之下,TPUNB奔跑的一年-IOTE物联网展 (baidu.com) 院士认可国际首创…...
[开源]研发管理项目,支持从需求到代码发布全过程全生命周期管理
一、开源项目简介 neatlogic-rdm支持从需求到代码发布全过程覆盖。具备需求管理、缺陷追踪、测试计划、测试用例、报表仪表板等功能,支持关联外部代码库如GitLab、GitHub等。个性化的属性配置和状态流转控制,能帮助用户管理不同类型项目。 二、开源协议…...
一文生成猫眼电影热榜词云
1.爬取猫眼电影热榜数据 此次爬取的是电影票房的热榜电影名称,具体网站网址为猫眼电影热榜,经过实验观察后发现,此处的数据是通过ajax异步加载的,如果不相信可以使用request对当前网站网址发送请求,会发现无法获取电影…...
监控脚本展示
需求: 监控SVQC,SVCD,FHTC,FHQC,FHCD文件的生成 监控服务器:10.10.3.56 监控路径:/data/app/datafile/ftp/qdttec/10000002/download/yyyyMMdd/* 监控时间:每天7点开始,2…...
【重拾C语言】五、模块化程序设计——函数(定义、调用、参数传递、结果返回、函数原型;典例:打印字符图形、验证哥德巴赫猜想)
目录 前言 五、模块化程序设计——函数 5.1 计算三角形的重心 5.2 函数 5.2.1 函数定义 5.2.2 函数调用 a. 函数调用的形式和过程 b. 参数传递 值传递 指针传递 c. 函数结果返回 5.2.3 函数原型(先调用后定义) 5.3 程序设计实例 5.3.1 打印…...
Unity实现设计模式——迭代器模式
Unity实现设计模式——迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式…...
【数据结构与算法】之“堆”介绍
目录 堆的基本存储 一、概念及其介绍 二、适用说明 三、结构图示 堆的 shift up 堆的 shift down 基础堆排序 一、概念及其介绍 二、适用说明 三、过程图示 优化堆排序 索引堆及其优化 一、概念及其介绍 二、适用说明 三、结构图示 堆的基本存储 一、概念及其介…...
ncnn Fatal signal 11 (SIGSEGV) 使用GPU加速崩溃
如果你的报错堆栈中包含以下信息,其中的关键信息是 anon:dalvik-classes2.dex extracted in memory Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x3c in tid 8619 (eplabv3plusncnn), pid 8619 () 2023-10-07 15:48:31.395 9793-9793 DEBUG …...
计算机考研 | 2018年 | 计算机组成原理真题
文章目录 【计算机组成原理2018年真题44题-15分】【第一步:信息提取】【第二步:具体解答】 【计算机组成原理2018年真题45题-8分】【第一步:信息提取】【第二步:具体解答】 【计算机组成原理2018年真题44题-15分】 某计算机采用页…...
用Configuration注解的方式写一个java过滤器的详细实例?
在Java中,可以使用Configuration注解和Spring框架来创建和配置过滤器。下面是一个详细的示例: 首先,创建一个实现javax.servlet.Filter接口的过滤器类,例如MyFilter: import javax.servlet.*; import java.io.IOExce…...
基于Springboot实现旧物置换网站平台演示【项目源码+论文说明】分享
基于Springboot实现旧物置换网站平台演示 摘要 随着时代在一步一步在进步,旧物也成人们的烦恼,许多平台网站都在推广自已的产品像天猫、咸鱼、京东。所以开发出一套关于旧物置换网站成为必需。旧物置换网站主要是借助计算机,通过对用户进行管…...
想要精通算法和SQL的成长之路 - 存在重复元素
想要精通算法和SQL的成长之路 - 存在重复元素 前言一. 存在重复元素II二. 存在重复元素III2.1 基于红黑树增删改查 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 存在重复元素II 原题链接 思路: 我们用HashSet存储元素,做到去重的效果。同时存储…...
使用华为eNSP组网试验⑸-访问控制
今天练习使用华为sNSP模拟网络设备上的访问控制,这样的操作我经常在华为的S7706、S5720、S5735或者H3C的S5500、S5130、S7706上进行,在网络设备上根据情况应用访问控制的策略是一个网管必须熟练的操作,只是在真机上操作一般比较谨慎ÿ…...
iPhone苹果手机闹钟智能跳过节假日怎么设置?
国内绝大多数的手机用户使用的操作系统只有三个,安卓、鸿蒙和苹果的ios。而iPhone苹果手机的忠实用户是非常多的,所以日积月累中用户数量也就非常庞大,并且相当一部分用户都是上班族。而工作忙碌的上班族因为事情比较多,为了避免自…...
TenDB Cluster 简介
文章目录 1.简介2.TSpider3.TenDB4.Tdbctl5.TenDB Cluster Operator参考文献 1.简介 TenDB Cluster 是腾讯游戏 CROS DBA 团队提供的 MySQL 分布式关系型数据库解决方案。主要特点包括:透明分库分表、高可用的 MySQL 集群服务,透明及在线的扩容及缩容&a…...
【刷题笔记10.6】LeetCode:翻转二叉树
LeetCode:翻转二叉树 一、题目描述 给你一颗二叉树的根节点root,翻转这颗二叉树,并返回其根节点。 二、分析 我们在做二叉树题目时候,第一想到的应该是用 递归 来解决。 仔细看下题目的 输入 和 输出,输出的左右…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
