设计模式——责任链模式

责任链模式 (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. 动态指定:需要动态指定处理者

常见应用场景

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

使用建议

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

注意事项

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

  • 不要让链太长,影响性能
  • 确保链不会断裂
相关推荐
Zane19941 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
怕浪猫2 天前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane19942 天前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19943 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..4 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
xiaofeiyang1504 天前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
Shadow(⊙o⊙)5 天前
OTOL设计模式 One Thread One Loop
服务器·网络·设计模式
sarasuki5 天前
如何让LLM 能在半夜偷偷打开网易云呢?
人工智能·设计模式·agent
小王师傅665 天前
【设计模式】装饰模式(四):框架源码实战——从 Java I/O 到 Spring 到 MyBatis
java·设计模式
执明wa5 天前
Android RecyclerView 多类型, 多种 Item
android·xml·开发语言·设计模式·android studio