责任链模式(ChainofResponsibilityPattern)

news/2024/12/28 10:10:52/

文章目录

  • 1.定义
  • 2.结构
  • 3.问题描述
  • 代码实现

1.定义

允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
在这里插入图片描述

2.结构

在这里插入图片描述

  • 处理者(Handler):声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法。
  • 基础处理者(Base Handler):是一个可选的类, 你可以将所有处理者共用的样本代码放置在其中。
    通常情况下, 该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。 该类还可以实现默认的处理行为: 确定下个处理者存在后再将请求传递给它。
  • 具体处理者(Concrete Handlers) :包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。
    处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
  • 客户端 (Client):可根据程序逻辑一次性或者动态地生成链。 值得注意的是, 请求可发送给链上的任意一个处理者, 而非必须是第一个处理者。

3.问题描述

    以公司采购东西为例子来实现责任链模式。公司规定:

  • 采购总价 < 10000.0,处理人:经理(Manager)
  • 10000.0 < 采购总价 < 25000.0,处理人:副总(VicePresident)
  • 25000.0 < 采购总价 < 100000.0,处理人:总经理(President)

    对于这样一个需求,最直观的方法就是设计一个方法,参数是采购的总价,然后在这个方法内对价格进行调整判断,然后针对不同的条件交给不同级别的人去处理,这样确实可以解决问题,但这样一来,我们就需要多重if-else语句来进行判断,但当加入一个新的条件范围时,我们又不得不去修改原来设计的方法来再添加一个条件判断,这样的设计显然违背了“开-闭”原则。这时候,可以采用责任链模式来解决这样的问题。

代码实现

采购请求:

// 采购请求
public class PurchaseRequest
{public double Amount; // 金额public string? ProductName{get; set;} // 产品名public PurchaseRequest(string productName, double amount){ProductName = productName;Amount = amount;}
}

审批人(抽象类):

// 审批人,handler
public abstract class Approver
{public string? Name{get; set;}private Approver? _nextApprover;public Approver(string name){Name = name;}// 设置下一个审批人public Approver SteNextApprover(Approver approver){_nextApprover = approver;return approver;}// 审批public virtual void Handle(PurchaseRequest request){if (_nextApprover != null)_nextApprover.Handle(request);elseConsole.WriteLine("事件链无法处理该请求");}
}

具体审批人:

// 经理
public class Manager : Approver
{public Manager(string name) : base(name){}public override void Handle(PurchaseRequest request){if (request.Amount < 10000.0)Console.WriteLine($"Manager({Name})处理了请求采购请求({request.ProductName}, {request.Amount})");elsebase.Handle(request);}
}// 副总
public class VicePresident : Approver
{public VicePresident(string name) : base(name){}public override void Handle(PurchaseRequest request){if (request.Amount < 25000.0)Console.WriteLine($"VicePresident({Name})处理了请求采购请求({request.ProductName}, {request.Amount})");elsebase.Handle(request);}
}// 总经理
public class President : Approver
{public President(string name) : base(name){}public override void Handle(PurchaseRequest request){if (request.Amount < 100000.0)Console.WriteLine($"President({Name})处理了请求采购请求({request.ProductName}, {request.Amount})");elsebase.Handle(request);}
}

客户端:

Console.WriteLine("----------------------- 责任链模式 ----------------------------");
PurchaseRequest requestTelphone = new PurchaseRequest("Telphone", 4000.0);
PurchaseRequest requestSoftware = new PurchaseRequest("Visual Studio", 10000.0);
PurchaseRequest requestComputers = new PurchaseRequest("Computers", 40000.0);Approver manager = new Manager("LearningHard");
Approver Vp = new VicePresident("Tony");
Approver Pre = new President("BossTom");// 设置责任链
manager.SteNextApprover(Vp).SteNextApprover(Pre);// 处理请求
manager.Handle(requestTelphone);
manager.Handle(requestSoftware);
manager.Handle(requestComputers);Vp.Handle(requestSoftware);

Manager(LearningHard)处理了请求采购请求(Telphone, 4000)
VicePresident(Tony)处理了请求采购请求(Visual Studio, 10000)
President(BossTom)处理了请求采购请求(Computers, 40000)
VicePresident(Tony)处理了请求采购请求(Visual Studio, 10000)


http://www.ppmy.cn/news/1558756.html

相关文章

预约参观华为基地,见证行业巅峰

✨ 大家好呀&#xff01;今天要跟大家分享一个超酷的体验&#xff0c;关于华为的参观学习之旅&#xff01;&#x1f680; 华为成立于1987年&#xff0c;位于深圳&#xff0c;是全球领先的信息与通信技术&#xff08;ICT&#xff09;解决方案供应商哦&#xff01;他们专注于科技…

git使用-小白入门

git使用-小白入门 安装一.创建版本库第一步 建立一个空目前第二步 用git init设置成GIT可管理的仓库。第一步 ⽤git add把⽂件添加到仓库第二步 ⽤git commit把⽂件提交到仓库 二.查看历史版本2.1用git status查看仓库的状态2.2用git diff查看修改的内容2.3 将修改过的文件add添…

2- Linux系统的命令帮助

Linux 命令行帮助信息使用指南 一、引言 对于初学者来说,Linux命令行可能会显得复杂和难以捉摸。然而,一旦掌握了如何有效地利用命令行的帮助信息,您将发现它是一个强大而灵活的工具,可以极大地提高您的工作效率。本指南旨在为新手介绍如何在Linux中获取命令的帮助信息,…

AI笔记-查漏补缺

https://www.zhihu.com/people/studyisalifestyle 1.V100&#xff0c;A800和A10卡的区别&#xff1a; NVIDIA的V100&#xff0c;A800和A10都是显卡或GPU&#xff0c;但他们针对的使用场景和性能有一些差别&#xff1a; Tesla V100: 这款显卡是NVIDIA专门为数据中心&#xff0…

各种网站(学习资源、常用工具及其他,持续更新中~)

欢迎围观笔者的个人博客~ 也欢迎通过RSS网址https://kangaroogao.github.io/atom.xml进行订阅~ 大学指南 上海交通大学生存手册中国科学技术大学人工智能与数据科学学院本科进阶指南USTC不完全入学指南大学生活质量指北科研论 信息搜集 AI信息搜集USTC飞跃网站计算机保研 技…

Boost之log日志使用

不讲理论&#xff0c;直接上在程序中可用代码&#xff1a; 一、引入Boost模块 开发环境&#xff1a;Visual Studio 2017 Boost库版本&#xff1a;1.68.0 安装方式&#xff1a;Nuget 安装命令&#xff1a; #只安装下面几个即可 Install-package boost -version 1.68.0 Install…

领域自适应

领域自适应&#xff08;Domain Adaptation&#xff09;是一种技术&#xff0c;用于将机器学习模型从一个数据分布&#xff08;源域&#xff09;迁移到另一个数据分布&#xff08;目标域&#xff09;。这在源数据和目标数据具有不同特征分布但任务相同的情况下特别有用。领域自适…

【Maven】Maven的快照库和发行库

1、分类 Maven 支持两种类型的仓库&#xff1a;快照库&#xff08;Snapshot Repository&#xff09;和发行库&#xff08;Release Repository&#xff09;&#xff0c;用于存储不同性质的构件&#xff08;Artifacts&#xff09;。 (1) 快照库 (Snapshot Repository)&#xff…