职责链模式,非常容易被忽视的设计模式之一(设计模式与开发实践 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,翻转这颗二叉树,并返回其根节点。 二、分析 我们在做二叉树题目时候,第一想到的应该是用 递归 来解决。 仔细看下题目的 输入 和 输出,输出的左右…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...