设计模式——责任链模式

责任链模式 (Chain of Responsibility Pattern)

什么是责任链模式?

责任链模式是一种行为型设计模式,它允许你将请求沿着处理者链传递,直到有一个处理者能够处理该请求。

简单来说:责任链模式就是"踢皮球",一个处理不了就传给下一个。

生活中的例子

想象一下:

  • 审批流程:员工请假 → 部门经理 → 人事经理 → 总经理
  • 客服系统:一级客服 → 二级客服 → 技术支持
  • 异常处理:try → catch → finally

为什么需要责任链模式?

传统方式的问题

java 复制代码
// 使用if-else处理
if (level == 1) {
    manager1.handle();
} else if (level == 2) {
    manager2.handle();
} else if (level == 3) {
    manager3.handle();
}

问题:

  1. 代码臃肿:大量if-else导致代码臃肿
  2. 难以扩展:新增处理者需要修改代码
  3. 耦合度高:客户端与所有处理者耦合

责任链模式的优势

java 复制代码
// 使用责任链
handler1.setNext(handler2);
handler2.setNext(handler3);
handler1.handle(request);

优势:

  1. 解耦合:发送者和接收者解耦
  2. 灵活扩展:可以灵活地添加或删除处理者
  3. 动态组合:可以动态地组合处理者链

责任链模式的结构

复制代码
┌─────────────────────┐
│      Handler        │  处理者接口
├─────────────────────┤
│ - next: Handler     │
│ + setNext(): void   │
│ + handle(): void    │
└──────────┬──────────┘
           │ 继承
           ├──┬──────────────────┬──────────────┐
           │                    │              │
┌──────────┴──────┐  ┌───────────┴───────┐  ┌───┴────────┐
│ ConcreteHandler1│  │ ConcreteHandler2 │  │ ...       │  具体处理者
├─────────────────┤  ├───────────────────┤  ├────────────┤
│ + handle()      │  │ + handle()        │  │            │
└─────────────────┘  └───────────────────┘  └────────────┘

代码示例

1. 定义处理者接口

java 复制代码
/**
 * 抽象处理者:请假审批
 */
public abstract class LeaveApproval {
    protected LeaveApproval next;
    protected String name;
    
    public LeaveApproval(String name) {
        this.name = name;
    }
    
    public void setNext(LeaveApproval next) {
        this.next = next;
    }
    
    /**
     * 处理请假请求
     * @param days 请假天数
     */
    public abstract void handle(int days);
}

2. 定义具体处理者

java 复制代码
/**
 * 具体处理者:主管
 */
public class Supervisor extends LeaveApproval {
    public Supervisor(String name) {
        super(name);
    }
    
    @Override
    public void handle(int days) {
        if (days <= 3) {
            System.out.println(name + "批准了" + days + "天的请假");
        } else if (next != null) {
            next.handle(days);
        } else {
            System.out.println("无人能处理" + days + "天的请假");
        }
    }
}

/**
 * 具体处理者:经理
 */
public class Manager extends LeaveApproval {
    public Manager(String name) {
        super(name);
    }
    
    @Override
    public void handle(int days) {
        if (days <= 7) {
            System.out.println(name + "批准了" + days + "天的请假");
        } else if (next != null) {
            next.handle(days);
        } else {
            System.out.println("无人能处理" + days + "天的请假");
        }
    }
}

/**
 * 具体处理者:总监
 */
public class Director extends LeaveApproval {
    public Director(String name) {
        super(name);
    }
    
    @Override
    public void handle(int days) {
        if (days <= 14) {
            System.out.println(name + "批准了" + days + "天的请假");
        } else if (next != null) {
            next.handle(days);
        } else {
            System.out.println("无人能处理" + days + "天的请假");
        }
    }
}

/**
 * 具体处理者:CEO
 */
public class CEO extends LeaveApproval {
    public CEO(String name) {
        super(name);
    }
    
    @Override
    public void handle(int days) {
        if (days <= 30) {
            System.out.println(name + "批准了" + days + "天的请假");
        } else {
            System.out.println("无人能处理" + days + "天的请假");
        }
    }
}

3. 使用责任链

java 复制代码
/**
 * 责任链模式测试类
 * 演示如何使用责任链模式处理请假审批
 */
public class ChainOfResponsibilityTest {
    
    public static void main(String[] args) {
        System.out.println("=== 责任链模式测试 ===\n");
        
        // 创建处理者
        LeaveApproval supervisor = new Supervisor("主管");
        LeaveApproval manager = new Manager("经理");
        LeaveApproval director = new Director("总监");
        LeaveApproval ceo = new CEO("CEO");
        
        // 设置责任链
        supervisor.setNext(manager);
        manager.setNext(director);
        director.setNext(ceo);
        
        // 测试不同天数的请假
        System.out.println("--- 请假1天 ---");
        supervisor.handle(1);
        
        System.out.println("\n--- 请假3天 ---");
        supervisor.handle(3);
        
        System.out.println("\n--- 请假7天 ---");
        supervisor.handle(7);
        
        System.out.println("\n--- 请假15天 ---");
        supervisor.handle(15);
        
        System.out.println("\n--- 请假35天 ---");
        supervisor.handle(35);
        
        System.out.println("\n=== 责任链模式的优势 ===");
        System.out.println("1. 解耦合:发送者和接收者解耦");
        System.out.println("2. 灵活扩展:可以灵活地添加或删除处理者");
        System.out.println("3. 动态组合:可以动态地组合处理者链");
        System.out.println("4. 简化代码:简化客户端代码");
        
        System.out.println("\n=== 实际应用场景 ===");
        System.out.println("1. 审批流程:请假审批、报销审批");
        System.out.println("2. 异常处理:异常处理链");
        System.out.println("3. 日志处理:日志处理链");
        System.out.println("4. 事件处理:事件处理链");
    }
}

责任链模式的优点

  1. 解耦合:发送者和接收者解耦
  2. 灵活扩展:可以灵活地添加或删除处理者
  3. 动态组合:可以动态地组合处理者链
  4. 简化代码:简化客户端代码

责任链模式的缺点

  1. 性能问题:请求可能沿着链传递多次
  2. 调试困难:难以追踪请求的处理过程
  3. 链断裂:如果链断裂,请求可能无法被处理

适用场景

  1. 多个处理者:有多个对象可以处理请求
  2. 不确定处理者:不确定哪个对象可以处理请求
  3. 动态指定:需要动态指定处理者

常见应用场景

  • 审批流程:请假审批、报销审批
  • 异常处理:异常处理链
  • 日志处理:日志处理链

使用建议

  • 多个处理者:使用责任链模式
  • 不确定处理者:使用责任链模式
  • 单一处理者:直接使用即可

注意事项

⚠️ 责任链模式虽然有用,但要注意:

  • 不要让链太长,影响性能
  • 确保链不会断裂
相关推荐
拆房老料1 分钟前
【第四部分:Agentic 智能体设计模式】15.为什么 Agent 也需要设计模式
人工智能·设计模式·ai·ai-native
geovindu1 小时前
rust: Chain of Responsibility Pattern (续)
开发语言·后端·设计模式·rust·责任链模式·行为模式
Lost of 程序猿2 小时前
责任链模式实战:审批流里“层层把关“的艺术
后端·设计模式·asp.net·责任链模式
希洛兔18 小时前
状态模式详解:让对象随内部状态自动改变行为
java·设计模式·状态模式
博风21 小时前
7、设计模式应用举例:策略模式:加密、解密文件
设计模式·策略模式
4SAPI21 小时前
Provider Adapter设计模式:如何让AI应用支持多个模型
网络·人工智能·设计模式
geovindu1 天前
rust: pool Pattern
开发语言·后端·设计模式·rust·对象池简写模式
高晶1 天前
ARM 嵌入式 Linux 开发:从体系结构到 LED 点亮实战
设计模式·程序员
VimorphTech1 天前
接入两套 TTS 接口后,业务代码如何避免堆满 if/else?
设计模式
geovindu1 天前
rust: pool Pattern (续)
开发语言·后端·设计模式·rust·对象池简写模式