责任链模式

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,它通过将多个处理器(Handler)按顺序连接起来,使请求沿着链条传递,直到被某个处理器处理或到达链尾。每个处理器只关心自己能处理的部分,无法处理的请求则传递给下一个处理器。责任链模式的核心思想是解耦请求发送者和请求处理者,使得请求的发送方不必知道具体的处理逻辑。

1. 责任链模式的结构

责任链模式通常包括以下几个核心角色:

  1. 抽象处理者(Handler):定义了处理请求的接口或抽象类,通常包含一个 handleRequest() 方法和一个指向下一个处理者的引用。
  2. 具体处理者(Concrete Handler):实现 Handler 的接口或继承 Handler 抽象类,负责处理特定类型的请求。每个具体处理者都包含一个对下一个处理者的引用,当无法处理请求时,将请求传递给下一个处理者。
  3. 客户端(Client):创建具体的处理者,并将它们按顺序链接起来,形成责任链。客户端将请求提交到责任链的起点,之后请求沿着链条传递,直到被处理或到达链尾。

责任链模式的 UML 类图

plaintextCopy code+----------------+      +-------------------------+
|   Client       |----->|      Handler            |
+----------------+      +-------------------------+
                            |+ handleRequest()     |
                            |+ setNext(Handler)    |
                            +----------------------+
                                         |
                                         |
                                         |
                 +-----------------------+------------------------+
                 |                                                |
                 V                                                V
         +-------------------+                          +-------------------+
         | ConcreteHandlerA  |                          | ConcreteHandlerB  |
         +-------------------+                          +-------------------+
         |+ handleRequest()  |                          |+ handleRequest()  |
         +-------------------+                          +-------------------+

2. 责任链模式的实现

假设我们有一个支持不同等级审批的系统,处理来自员工的请假请求。不同的审批层级负责不同的天数范围,比如普通经理可以审批 1-3 天的请假,部门经理可以审批 4-7 天,HR 负责人可以审批超过 7 天的请求。

1. 定义抽象处理者接口

javaCopy codepublic abstract class LeaveHandler {
    protected LeaveHandler nextHandler;

    public void setNextHandler(LeaveHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public abstract void handleRequest(int leaveDays);
}

2. 创建具体处理者

经理审批(处理 1-3 天的请假)
javaCopy codepublic class ManagerHandler extends LeaveHandler {
    @Override
    public void handleRequest(int leaveDays) {
        if (leaveDays <= 3) {
            System.out.println("经理批准了 " + leaveDays + " 天的请假");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(leaveDays);
        }
    }
}
部门经理审批(处理 4-7 天的请假)
javaCopy codepublic class DepartmentManagerHandler extends LeaveHandler {
    @Override
    public void handleRequest(int leaveDays) {
        if (leaveDays <= 7) {
            System.out.println("部门经理批准了 " + leaveDays + " 天的请假");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(leaveDays);
        }
    }
}
HR 负责人审批(处理超过 7 天的请假)
javaCopy codepublic class HRHandler extends LeaveHandler {
    @Override
    public void handleRequest(int leaveDays) {
        if (leaveDays > 7) {
            System.out.println("HR 批准了 " + leaveDays + " 天的请假");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(leaveDays);
        }
    }
}

3. 客户端设置责任链并发起请求

javaCopy codepublic class Client {
    public static void main(String[] args) {
        // 创建具体的处理者
        LeaveHandler manager = new ManagerHandler();
        LeaveHandler departmentManager = new DepartmentManagerHandler();
        LeaveHandler hr = new HRHandler();

        // 设置责任链
        manager.setNextHandler(departmentManager);
        departmentManager.setNextHandler(hr);

        // 发起请求
        System.out.println("请求 2 天请假:");
        manager.handleRequest(2);

        System.out.println("\n请求 5 天请假:");
        manager.handleRequest(5);

        System.out.println("\n请求 10 天请假:");
        manager.handleRequest(10);
    }
}
输出结果:
plaintextCopy code请求 2 天请假:
经理批准了 2 天的请假

请求 5 天请假:
部门经理批准了 5 天的请假

请求 10 天请假:
HR 批准了 10 天的请假

3. 责任链模式的优缺点

优点

  1. 降低耦合度:请求发送者和处理者解耦,发送者无需关心具体哪个处理者来处理请求。
  2. 灵活性高:责任链的节点可以灵活组合、扩展和重用,增加或修改处理者不会影响其他处理者。
  3. 链式处理:请求可以按顺序被多个处理者处理,且可以动态改变链条的结构,满足不同业务场景的需求。

缺点

  1. 请求可能没有被处理:如果没有适合的处理者,可能会导致请求未被处理的情况,除非在链尾加一个默认处理者。
  2. 性能问题:如果链条过长,可能导致请求处理速度变慢。
  3. 调试困难:由于请求沿链条传播,可能难以调试和定位请求在哪个节点上被处理。

4. 责任链模式的应用场景

责任链模式适用于以下场景:

  1. 多个对象处理同一请求,且处理顺序需要灵活调整:如审批流程、权限验证、日志处理等。
  2. 动态指定处理者:请求的处理者在运行时动态确定,比如动态配置业务处理流程。
  3. 请求处理条件复杂:当有多个条件判断去决定请求的处理流程时,责任链模式可以减少代码中的条件判断,使代码更清晰。

5. 责任链模式的扩展与优化

1. 默认处理者

在链的末尾增加一个默认处理者,以确保请求总是会被处理。例如,设置一个“无权限”的处理者,在所有具体处理者都无法处理时执行默认行为,避免请求丢失。

2. 灵活配置链条

使用配置文件或数据库来配置责任链的顺序,以便根据不同需求动态改变处理者的顺序。这种方式通常与工厂模式结合使用。

3. 变种:双向链表

标准的责任链是单向链表结构。如果需要实现请求在失败时回退到前一个处理者,可以使用双向链表结构,让每个处理者既有前继节点又有后继节点,适应更复杂的业务场景。

6. 总结

  • 责任链模式 是一种将请求处理从客户端解耦的模式,允许多个处理者对请求进行按顺序处理。
  • 核心思想:请求从一个处理者传递到下一个处理者,直到被处理或到达链尾。
  • 优点:低耦合、灵活配置处理者,减少条件判断。
  • 应用场景:适合审批流程、日志处理、权限校验等需要灵活组合处理步骤的场景。
0 0 投票数
Article Rating
订阅评论
提醒
guest
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x