设计模式——责任链模式

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

常见应用场景

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

使用建议

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

注意事项

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

  • 不要让链太长,影响性能
  • 确保链不会断裂
相关推荐
小湘西9 分钟前
拓扑排序(Topological Sort)
python·设计模式
蜜獾云4 小时前
设计模式之观察者模式:监听目标对象的状态改变
观察者模式·设计模式·rxjava
知无不研4 小时前
中介者模式
c++·设计模式·中介者模式
bmseven5 小时前
大白话讲解23种设计模式简介
设计模式
蜜獾云5 小时前
设计模式之代理模式:本地接口代理远程接口的调用
设计模式·系统安全·代理模式
蜜獾云5 小时前
设计模式之访问者模式:动态的给目标对象增加新功能
设计模式·访问者模式
蜜獾云7 小时前
设计模式之策略模式:替换掉糟糕的if else语句实现面向对象编程而非面向过程
设计模式·策略模式
蜜獾云7 小时前
设计模式之状态模式:封装数据的状态流转逻辑
设计模式·状态模式
Serene_Dream7 小时前
深度解析设计模式:单例模式(Singleton Pattern)
单例模式·设计模式
朱一头zcy7 小时前
设计模式入门:最简单的单例模式
笔记·单例模式·设计模式