责任链设计模式详解

责任链设计模式详解

一、责任链模式概述

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理链传递,直到有一个处理者处理它。这种模式让多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

核心概念

  • 处理者:定义处理请求的接口
  • 具体处理者:实现处理请求的具体逻辑
  • :将处理者连接起来,形成处理链

二、责任链模式的结构

2.1 UML 类图

复制代码
┌─────────────┐    ┌─────────────────┐
│   Client    │    │   Handler       │
│             │    │                 │
│ +main()     │    │ +handleRequest()│
└─────────────┘    │ +setNext()      │
       │           └─────────────────┘
       │                     △
       │                     │
       │           ┌─────────────────┐
       └───────────│ ConcreteHandler │
                   │                 │
                   │ +handleRequest()│
                   └─────────────────┘

2.2 核心角色

  1. Handler(抽象处理者):定义处理请求的接口
  2. ConcreteHandler(具体处理者):实现具体的处理逻辑
  3. Client(客户端):创建处理链并向链头发送请求

三、责任链模式的实现

3.1 基础实现

步骤1:定义抽象处理者
java 复制代码
/**
 * 抽象处理者 - 审批人
 */
public abstract class Approver {
    protected Approver nextApprover;  // 下一个处理者
    protected String name;            // 处理者名称
    
    public Approver(String name) {
        this.name = name;
    }
    
    // 设置下一个处理者
    public Approver setNext(Approver nextApprover) {
        this.nextApprover = nextApprover;
        return this.nextApprover;  // 返回下一个处理者,支持链式调用
    }
    
    // 处理审批请求的抽象方法
    public abstract void processRequest(PurchaseRequest request);
}
步骤2:定义请求对象
java 复制代码
/**
 * 采购请求 - 请求对象
 */
public class PurchaseRequest {
    private int type;        // 请求类型
    private int number;      // 请求编号
    private float price;     // 金额
    private String purpose;  // 用途
    
    public PurchaseRequest(int type, int number, float price, String purpose) {
        this.type = type;
        this.number = number;
        this.price = price;
        this.purpose = purpose;
    }
    
    // getter 方法
    public int getType() { return type; }
    public int getNumber() { return number; }
    public float getPrice() { return price; }
    public String getPurpose() { return purpose; }
}
步骤3:实现具体处理者
java 复制代码
/**
 * 具体处理者 - 部门经理
 */
public class DepartmentManager extends Approver {
    
    public DepartmentManager(String name) {
        super(name);
    }
    
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() <= 5000) {
            // 部门经理可以审批5000元以下的采购
            System.out.println("请求编号: " + request.getNumber() + 
                             ",金额: " + request.getPrice() + 
                             ",目的: " + request.getPurpose());
            System.out.println("审批人: " + this.name + " [部门经理]");
        } else if (nextApprover != null) {
            // 超过权限,传递给下一个处理者
            System.out.println("部门经理 " + name + " 无权审批,转交上级...");
            nextApprover.processRequest(request);
        } else {
            // 没有下一个处理者,审批失败
            System.out.println("请求无法处理,审批链结束");
        }
    }
}

/**
 * 具体处理者 - 副总经理
 */
public class ViceGeneralManager extends Approver {
    
    public ViceGeneralManager(String name) {
        super(name);
    }
    
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() <= 10000) {
            // 副总经理可以审批10000元以下的采购
            System.out.println("请求编号: " + request.getNumber() + 
                             ",金额: " + request.getPrice() + 
                             ",目的: " + request.getPurpose());
            System.out.println("审批人: " + this.name + " [副总经理]");
        } else if (nextApprover != null) {
            // 超过权限,传递给下一个处理者
            System.out.println("副总经理 " + name + " 无权审批,转交上级...");
            nextApprover.processRequest(request);
        } else {
            System.out.println("请求无法处理,审批链结束");
        }
    }
}

/**
 * 具体处理者 - 总经理
 */
public class GeneralManager extends Approver {
    
    public GeneralManager(String name) {
        super(name);
    }
    
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() <= 50000) {
            // 总经理可以审批50000元以下的采购
            System.out.println("请求编号: " + request.getNumber() + 
                             ",金额: " + request.getPrice() + 
                             ",目的: " + request.getPurpose());
            System.out.println("审批人: " + this.name + " [总经理]");
        } else {
            // 超过总经理权限,需要董事会审批
            System.out.println("金额过大(" + request.getPrice() + 
                             "),需要召开董事会讨论");
        }
    }
}
步骤4:客户端使用
java 复制代码
/**
 * 客户端 - 测试责任链模式
 */
public class ChainOfResponsibilityClient {
    public static void main(String[] args) {
        // 1. 创建处理者
        Approver departmentManager = new DepartmentManager("张经理");
        Approver viceManager = new ViceGeneralManager("李副总");
        Approver generalManager = new GeneralManager("王总经理");
        
        // 2. 构建责任链:部门经理 -> 副总经理 -> 总经理
        departmentManager.setNext(viceManager).setNext(generalManager);
        
        // 3. 创建不同的采购请求
        System.out.println("=== 测试责任链模式 ===");
        
        // 请求1:3000元,应该由部门经理审批
        PurchaseRequest request1 = new PurchaseRequest(1, 1001, 3000, "购买办公用品");
        System.out.println("\n请求1: 3000元采购");
        departmentManager.processRequest(request1);
        
        // 请求2:8000元,应该由副总经理审批
        PurchaseRequest request2 = new PurchaseRequest(2, 1002, 8000, "部门团队建设");
        System.out.println("\n请求2: 8000元采购");
        departmentManager.processRequest(request2);
        
        // 请求3:30000元,应该由总经理审批
        PurchaseRequest request3 = new PurchaseRequest(3, 1003, 30000, "购买服务器");
        System.out.println("\n请求3: 30000元采购");
        departmentManager.processRequest(request3);
        
        // 请求4:100000元,超过审批权限
        PurchaseRequest request4 = new PurchaseRequest(4, 1004, 100000, "公司车辆采购");
        System.out.println("\n请求4: 100000元采购");
        departmentManager.processRequest(request4);
    }
}

3.2 输出结果

复制代码
=== 测试责任链模式 ===

请求1: 3000元采购
请求编号: 1001,金额: 3000.0,目的: 购买办公用品
审批人: 张经理 [部门经理]

请求2: 8000元采购
部门经理 张经理 无权审批,转交上级...
请求编号: 1002,金额: 8000.0,目的: 部门团队建设
审批人: 李副总 [副总经理]

请求3: 30000元采购
部门经理 张经理 无权审批,转交上级...
副总经理 李副总 无权审批,转交上级...
请求编号: 1003,金额: 30000.0,目的: 购买服务器
审批人: 王总经理 [总经理]

请求4: 100000元采购
部门经理 张经理 无权审批,转交上级...
副总经理 李副总 无权审批,转交上级...
金额过大(100000.0),需要召开董事会讨论

四、责任链模式的进阶实现

4.1 使用集合管理处理链

java 复制代码
import java.util.ArrayList;
import java.util.List;

/**
 * 处理链管理器
 */
public class ApprovalChain {
    private List<Approver> approvers = new ArrayList<>();
    private int index = 0;  // 当前处理者索引
    
    // 添加处理者
    public void addApprover(Approver approver) {
        approvers.add(approver);
    }
    
    // 处理请求
    public void processRequest(PurchaseRequest request) {
        if (index < approvers.size()) {
            Approver currentApprover = approvers.get(index);
            index++;
            currentApprover.processRequest(request);
        } else {
            System.out.println("所有处理者都无法处理该请求");
        }
    }
    
    // 重置链(支持重复使用)
    public void reset() {
        index = 0;
    }
}

/**
 * 修改后的具体处理者(简化版)
 */
public class SimpleApprover extends Approver {
    private double maxAmount;
    
    public SimpleApprover(String name, double maxAmount) {
        super(name);
        this.maxAmount = maxAmount;
    }
    
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() <= maxAmount) {
            System.out.println("审批通过: " + name + " 审批了 " + request.getPrice() + "元");
        } else if (nextApprover != null) {
            System.out.println(name + " 无法审批,转交下一级");
            nextApprover.processRequest(request);
        } else {
            System.out.println("无人能够审批该请求");
        }
    }
}

// 使用示例
public class AdvancedChainExample {
    public static void main(String[] args) {
        // 创建处理链管理器
        ApprovalChain chain = new ApprovalChain();
        chain.addApprover(new SimpleApprover("经理", 5000));
        chain.addApprover(new SimpleApprover("总监", 20000));
        chain.addApprover(new SimpleApprover("总经理", 100000));
        
        // 处理多个请求
        PurchaseRequest[] requests = {
            new PurchaseRequest(1, 1001, 3000, "测试1"),
            new PurchaseRequest(2, 1002, 15000, "测试2"),
            new PurchaseRequest(3, 1003, 50000, "测试3"),
            new PurchaseRequest(4, 1004, 200000, "测试4")
        };
        
        for (PurchaseRequest request : requests) {
            System.out.println("\n处理请求: " + request.getPrice() + "元");
            chain.processRequest(request);
            chain.reset();  // 重置链以处理下一个请求
        }
    }
}

4.2 支持中断的责任链

java 复制代码
/**
 * 支持中断的抽象处理者
 */
public abstract class InterruptibleApprover {
    protected InterruptibleApprover nextApprover;
    
    public void setNext(InterruptibleApprover nextApprover) {
        this.nextApprover = nextApprover;
    }
    
    /**
     * 处理请求,返回true表示继续传递,false表示中断链
     */
    public abstract boolean processRequest(PurchaseRequest request);
}

/**
 * 具体处理者 - 支持中断
 */
public class InterruptibleDepartmentManager extends InterruptibleApprover {
    private String name;
    
    public InterruptibleDepartmentManager(String name) {
        this.name = name;
    }
    
    @Override
    public boolean processRequest(PurchaseRequest request) {
        if (request.getPrice() <= 5000) {
            System.out.println(name + " 审批了 " + request.getPrice() + "元");
            return false;  // 审批完成,中断链
        } else if (request.getPurpose().contains("紧急")) {
            System.out.println(name + " 处理紧急请求: " + request.getPurpose());
            // 紧急请求需要所有领导知晓,但不中断链
            return true;
        } else {
            System.out.println(name + " 无法审批,转交上级");
            return true;  // 继续传递
        }
    }
}

五、责任链模式在真实项目中的应用

5.1 Java Web 中的 Filter 链

java 复制代码
// 模拟Servlet Filter的责任链实现
public interface Filter {
    void doFilter(ServletRequest request, ServletResponse response, 
                  FilterChain chain);
}

public class FilterChain {
    private List<Filter> filters = new ArrayList<>();
    private int index = 0;
    
    public void addFilter(Filter filter) {
        filters.add(filter);
    }
    
    public void doFilter(ServletRequest request, ServletResponse response) {
        if (index < filters.size()) {
            Filter filter = filters.get(index);
            index++;
            filter.doFilter(request, response, this);
        }
        // 链执行完毕,执行实际业务逻辑
    }
}

// 具体过滤器
public class LoggingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) {
        System.out.println("日志记录: " + new Date());
        chain.doFilter(request, response);  // 继续下一个过滤器
        System.out.println("日志记录完成");
    }
}

public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) {
        if (isAuthenticated(request)) {
            chain.doFilter(request, response);
        } else {
            // 认证失败,中断链
            System.out.println("认证失败");
        }
    }
    
    private boolean isAuthenticated(ServletRequest request) {
        // 认证逻辑
        return true;
    }
}

5.2 事件处理系统

java 复制代码
/**
 * 事件处理器链
 */
public class EventHandlerChain {
    private List<EventHandler> handlers = new ArrayList<>();
    
    public void addHandler(EventHandler handler) {
        handlers.add(handler);
    }
    
    public boolean handleEvent(Event event) {
        for (EventHandler handler : handlers) {
            if (handler.canHandle(event)) {
                handler.handle(event);
                return true;  // 事件已处理
            }
        }
        return false;  // 没有处理器能处理该事件
    }
}

public interface EventHandler {
    boolean canHandle(Event event);
    void handle(Event event);
}

六、责任链模式的优缺点

优点:

  1. 降低耦合度:请求发送者不需要知道哪个对象会处理它的请求
  2. 增强灵活性:可以动态地增加或修改处理链
  3. 简化对象:每个处理者只需关注自己的责任范围
  4. 符合开闭原则:新增处理者无需修改现有代码

缺点:

  1. 请求可能未被处理:如果链中没有合适的处理者,请求可能得不到处理
  2. 性能影响:长链可能影响性能,特别是在链的遍历上
  3. 调试困难:请求的传递路径可能不直观,调试较复杂

七、适用场景

  1. 多级审批系统:如采购审批、请假审批等
  2. 事件处理系统:如GUI事件处理、异常处理
  3. 过滤器/拦截器链:如Web应用中的Filter、Interceptor
  4. 日志处理系统:不同级别的日志由不同处理器处理
  5. 数据验证链:多个验证规则依次执行

八、总结

责任链模式通过将请求的发送者和接收者解耦,提供了灵活的请求处理机制。在实际开发中,它特别适合于需要多级处理或动态处理流程的场景。

关键要点

  • 合理设计处理者的职责范围
  • 注意处理链的长度,避免性能问题
  • 考虑请求可能未被处理的情况
  • 支持动态调整处理链的顺序和内容

通过合理运用责任链模式,可以构建出灵活、可扩展的处理系统,大大提高代码的可维护性和可扩展性。

相关推荐
青草地溪水旁4 小时前
设计模式(C++)详解——职责链模式 (Chain of Responsibility)(2)
c++·设计模式·责任链模式
青草地溪水旁4 小时前
设计模式(C++)详解——职责链模式 (Chain of Responsibility)(1)
c++·设计模式·责任链模式
phdsky4 小时前
【设计模式】责任链模式
设计模式·责任链模式
yujkss4 小时前
23种设计模式之【责任链模式】-核心原理与 Java 实践
java·设计模式·责任链模式
天將明°6 小时前
命令模式指南:将请求封装成对象的灵活方案
c语言·设计模式·命令模式
yujkss6 小时前
23种设计模式之【命令模式】-核心原理与 Java 实践
设计模式
vker7 小时前
第 4 天:建造者模式(Builder Pattern)—— 创建型模式
java·后端·设计模式
new_daimond7 小时前
设计模式详解:单例模式、工厂方法模式、抽象工厂模式
单例模式·设计模式·工厂方法模式
bkspiderx9 小时前
C++设计模式之创建型模式:原型模式(Prototype)
c++·设计模式·原型模式