设计模式——责任链模式

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

常见应用场景

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

使用建议

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

注意事项

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

  • 不要让链太长,影响性能
  • 确保链不会断裂
相关推荐
evans在进步9 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
字节跳动开源15 小时前
VisActor全新图可视化开源项目:VGraph
前端·设计模式·开源
码匠许师傅16 小时前
【设计模式精讲】11.桥接模式(Bridge)
c++·设计模式·桥接模式·uml
学习星球2 天前
AI Agent 成本工程实战:从 OpenAI Codex 的 8 个“烧 Token“Bug 学起
人工智能·设计模式·微信小程序
AI人工智能+电脑小能手2 天前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理
Java后端的Ai之路2 天前
14、Python - 责任链模式
服务器·开发语言·人工智能·python·责任链模式
码匠许师傅3 天前
【设计模式精讲】7.建造者模式(Builder)
设计模式·建造者模式
码匠许师傅3 天前
【设计模式精讲】6.抽象工厂(Abstract Factory)
c++·设计模式
workflower3 天前
人形机器人灵巧手产业链
人工智能·设计模式·机器人·云计算·无人机
Java后端的Ai之路3 天前
03、Python - 抽象工厂模式
开发语言·python·设计模式·抽象工厂模式·通用智慧