职责链模式

69 阅读3分钟

职责链模式(Chain of Responsibility Pattern),是一种行为型设计模式,它允许请求沿着处理者链进行传递。每个处理者都可以选择是否处理该请求以及是否将请求继续传递给下一个处理者。这种模式解耦了请求的发送者和接收者,并且可以在运行时动态地指定一组处理者来处理请求。

职责链模式的特点

  1. 降低耦合度:发送者不需要知道具体的接收者是谁,只需将请求交给链上的第一个处理者即可。
  2. 增强灵活性:可以随时添加或移除处理者,而不会影响到其他部分的代码。
  3. 支持多步骤处理:对于需要经过多个步骤才能完成的任务,职责链模式提供了一种有序的方式来进行处理。
  4. 简化客户端代码:客户端只需要创建处理者链并提交请求,无需关心具体哪个处理者会处理这个请求。
  5. 可扩展性强:新增加一个处理者只需要实现相应的接口,并将其插入到链中适当的位置。

职责链模式的组成

  • Handler(抽象处理者) :定义了一个接口,用于封装处理请求的方法。所有具体处理者都必须实现这个接口。
  • ConcreteHandler(具体处理者) :实现了Handler接口,并包含了具体的处理逻辑。每个具体处理者都知道它的后继者是谁,并可以在必要时将请求传递给后继者。
  • Client(客户端) :创建处理者链,并向链中的第一个处理者提交请求。

职责链模式的实现

我们将通过一个简单的例子来演示职责链模式的应用:假设我们正在开发一个请假审批系统,员工提交的请假申请需要经过不同级别的领导审批(如小组长、部门经理、总经理)。我们可以使用职责链模式来管理这些审批流程,确保每次请假申请都能按照规定的顺序被正确的领导审核。

示例代码

// 抽象处理者 - Handler
abstract class LeaveApprover {
    protected LeaveApprover nextApprover;

    public void setNextApprover(LeaveApprover nextApprover) {
        this.nextApprover = nextApprover;
    }

    abstract void processRequest(LeaveRequest request);
}

// 具体处理者 - TeamLeaderApprover
class TeamLeaderApprover extends LeaveApprover {
    @Override
    void processRequest(LeaveRequest request) {
        if (request.getDays() <= 3) {
            System.out.println("Team Leader approved " + request.getDays() + " days leave.");
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理者 - DepartmentManagerApprover
class DepartmentManagerApprover extends LeaveApprover {
    @Override
    void processRequest(LeaveRequest request) {
        if (request.getDays() <= 7) {
            System.out.println("Department Manager approved " + request.getDays() + " days leave.");
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理者 - GeneralManagerApprover
class GeneralManagerApprover extends LeaveApprover {
    @Override
    void processRequest(LeaveRequest request) {
        if (request.getDays() > 7) {
            System.out.println("General Manager approved " + request.getDays() + " days leave.");
        }
    }
}

// 请求类 - LeaveRequest
class LeaveRequest {
    private int days;

    public LeaveRequest(int days) {
        this.days = days;
    }

    public int getDays() {
        return days;
    }
}

使用示例

public class ChainOfResponsibilityPatternDemo {
    public static void main(String[] args) {
        // 创建处理者链
        LeaveApprover teamLeader = new TeamLeaderApprover();
        LeaveApprover departmentManager = new DepartmentManagerApprover();
        LeaveApprover generalManager = new GeneralManagerApprover();

        teamLeader.setNextApprover(departmentManager);
        departmentManager.setNextApprover(generalManager);

        // 模拟员工提交请假申请
        LeaveRequest request1 = new LeaveRequest(2);
        LeaveRequest request2 = new LeaveRequest(5);
        LeaveRequest request3 = new LeaveRequest(10);

        teamLeader.processRequest(request1); // Team Leader approved 2 days leave.
        teamLeader.processRequest(request2); // Department Manager approved 5 days leave.
        teamLeader.processRequest(request3); // General Manager approved 10 days leave.
    }
}

职责链模式的应用场景

  • 当你有一个请求,但是不确定由谁来处理它,或者有多个对象可能处理该请求时。
  • 在构建日志记录系统时,可以根据不同的日志级别(如DEBUG, INFO, WARN, ERROR)决定哪些信息应该被记录下来。
  • 对于权限管理系统,可以根据用户的权限等级逐步检查是否有权执行某些操作。
  • 实现消息队列或事件驱动架构中,可以按照一定的顺序依次处理接收到的消息或事件。
  • 构建图形用户界面框架时,可以用来处理键盘和鼠标事件,直到某个组件愿意接受并处理它们。

结语

希望本文能帮助您更好地理解职责链模式的概念及其实际应用。如果您有任何疑问或建议,请随时留言交流。