【设计模式】责任链模式

责任链模式(Chain of Responsibility Pattern)

概念:

· 一种行为型设计模式;

· 核心思想是将请求的发送者和接收者解耦,让多个对象都有机会处理该请求,将这些对象连成一条链,并沿着这条链子传递请求,直到有对象能够处理这个请求为止

UML结构:

复制代码
       Handler (抽象处理者)
        + setNext(handler)
        + handleRequest(request)
               |
    -------------------------
    |           |           |
ConcreteHandler1 ConcreteHandler2 ConcreteHandler3
        |
      Client

代码示例:

cs 复制代码
/// <summary>
/// 抽象处理者
/// </summary>
public abstract class Employee
{
    protected Employee _next; // 上级处理者
    protected int _canApproval; // 可审批天数
    protected string _name;

    public Employee(string name, int canApproval)
    {
        _name = name;
        _canApproval = canApproval;
    }

    public void SetNext(Employee next)
    {
        _next = _next;
    }

    public void HandleRequest(int days)
    {
        if (days <= _canApproval)
        {
            Console.WriteLine($"{_name}审批成功,请假天数:{days}");
        }
        else if (_next != null)
        {
            Console.WriteLine($"{_name}无法审批,请求上报{_next._name}");
        }
        else
        {
            Console.WriteLine("审批失败,无人可处理!");
        }
    }
}

/// <summary>
/// 普通员工类(处理者1)
/// </summary>
public class OrdinaryEmployee : Employee
{
    public OrdinaryEmployee(string name, int canApproval) : base(name, canApproval) { }
}

/// <summary>
/// 部门经理类(处理者2)
/// </summary>
public class DepartmentManager : Employee
{
    public DepartmentManager(string name, int canApproval) : base(name, canApproval) { }
}

/// <summary>
/// 总经理类(处理者3)
/// </summary>
public class GeneralManager : Employee
{
    public GeneralManager(string name, int canApproval) : base(name, canApproval) { }
}

/// <summary>
/// 客户端
/// </summary>
public class Client
{
    public static void Main()
    {
        Employee generalManager = new GeneralManager("总经理", 30);
        Employee departmentManager = new DepartmentManager("部门经理", 5);
        Employee ordinaryEmployee = new OrdinaryEmployee("普通员工", 0);

        ordinaryEmployee.SetNext(departmentManager);
        departmentManager.SetNext(generalManager);

        ordinaryEmployee.HandleRequest(2);

        ordinaryEmployee.HandleRequest(10);

        departmentManager.HandleRequest(35);
    }
}

特点:
优点:

· 降低耦合度:请求发送者无需知道请求由谁处理;

· 增强灵活性:可动态调整责任链顺序或新增处理者;

· 符合单一职责原则:每个处理者只处理自己职责范围内的请求;
缺点:

· 可能产生链过长导致影响了性能;

· 请求可能到达末端都无人处理,因此需要额外的判断;

· 调试和跟踪困难,沿着链传递时,容易不清楚实际的处理者是谁;

适用场景:

· 请求有多个处理对象,但是不确定应该被哪一个处理(审批流程、事件处理、过滤器链);

· 希望动态处理顺序或增加新的处理者;

· 处理职责明确,各个执行处理者可分离;

举例:

· 公司请假审批;

· 日志处理系统(DEBUG、INFO、ERROR 级别日志交给不同日志处理器处理);

· Web请求过滤器链(身份认证 → 参数校验 → 请求记录 → 响应);

相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
EIP低代码平台3 小时前
EIP 低代码平台 - 角色维护
低代码·c#·权限·工作流·netcore
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨6 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜8 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript