责任链模式 (Chain of Responsibility Pattern)
什么是责任链模式?
责任链模式是一种行为型设计模式,它允许你将请求沿着处理者链传递,直到有一个处理者能够处理该请求。
简单来说:责任链模式就是"踢皮球",一个处理不了就传给下一个。
生活中的例子
想象一下:
- 审批流程:员工请假 → 部门经理 → 人事经理 → 总经理
- 客服系统:一级客服 → 二级客服 → 技术支持
- 异常处理:try → catch → finally
为什么需要责任链模式?
传统方式的问题
// 使用if-else处理if(level==1){manager1.handle();}elseif(level==2){manager2.handle();}elseif(level==3){manager3.handle();}问题:
- 代码臃肿:大量if-else导致代码臃肿
- 难以扩展:新增处理者需要修改代码
- 耦合度高:客户端与所有处理者耦合
责任链模式的优势
// 使用责任链handler1.setNext(handler2);handler2.setNext(handler3);handler1.handle(request);优势:
- 解耦合:发送者和接收者解耦
- 灵活扩展:可以灵活地添加或删除处理者
- 动态组合:可以动态地组合处理者链
责任链模式的结构
┌─────────────────────┐ │ Handler │ 处理者接口 ├─────────────────────┤ │ - next: Handler │ │ + setNext(): void │ │ + handle(): void │ └──────────┬──────────┘ │ 继承 ├──┬──────────────────┬──────────────┐ │ │ │ ┌──────────┴──────┐ ┌───────────┴───────┐ ┌───┴────────┐ │ ConcreteHandler1│ │ ConcreteHandler2 │ │ ... │ 具体处理者 ├─────────────────┤ ├───────────────────┤ ├────────────┤ │ + handle() │ │ + handle() │ │ │ └─────────────────┘ └───────────────────┘ └────────────┘代码示例
1. 定义处理者接口
/** * 抽象处理者:请假审批 */publicabstractclassLeaveApproval{protectedLeaveApprovalnext;protectedStringname;publicLeaveApproval(Stringname){this.name=name;}publicvoidsetNext(LeaveApprovalnext){this.next=next;}/** * 处理请假请求 * @param days 请假天数 */publicabstractvoidhandle(intdays);}2. 定义具体处理者
/** * 具体处理者:主管 */publicclassSupervisorextendsLeaveApproval{publicSupervisor(Stringname){super(name);}@Overridepublicvoidhandle(intdays){if(days<=3){System.out.println(name+"批准了"+days+"天的请假");}elseif(next!=null){next.handle(days);}else{System.out.println("无人能处理"+days+"天的请假");}}}/** * 具体处理者:经理 */publicclassManagerextendsLeaveApproval{publicManager(Stringname){super(name);}@Overridepublicvoidhandle(intdays){if(days<=7){System.out.println(name+"批准了"+days+"天的请假");}elseif(next!=null){next.handle(days);}else{System.out.println("无人能处理"+days+"天的请假");}}}/** * 具体处理者:总监 */publicclassDirectorextendsLeaveApproval{publicDirector(Stringname){super(name);}@Overridepublicvoidhandle(intdays){if(days<=14){System.out.println(name+"批准了"+days+"天的请假");}elseif(next!=null){next.handle(days);}else{System.out.println("无人能处理"+days+"天的请假");}}}/** * 具体处理者:CEO */publicclassCEOextendsLeaveApproval{publicCEO(Stringname){super(name);}@Overridepublicvoidhandle(intdays){if(days<=30){System.out.println(name+"批准了"+days+"天的请假");}else{System.out.println("无人能处理"+days+"天的请假");}}}3. 使用责任链
/** * 责任链模式测试类 * 演示如何使用责任链模式处理请假审批 */publicclassChainOfResponsibilityTest{publicstaticvoidmain(String[]args){System.out.println("=== 责任链模式测试 ===\n");// 创建处理者LeaveApprovalsupervisor=newSupervisor("主管");LeaveApprovalmanager=newManager("经理");LeaveApprovaldirector=newDirector("总监");LeaveApprovalceo=newCEO("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. 事件处理:事件处理链");}}责任链模式的优点
- 解耦合:发送者和接收者解耦
- 灵活扩展:可以灵活地添加或删除处理者
- 动态组合:可以动态地组合处理者链
- 简化代码:简化客户端代码
责任链模式的缺点
- 性能问题:请求可能沿着链传递多次
- 调试困难:难以追踪请求的处理过程
- 链断裂:如果链断裂,请求可能无法被处理
适用场景
- 多个处理者:有多个对象可以处理请求
- 不确定处理者:不确定哪个对象可以处理请求
- 动态指定:需要动态指定处理者
常见应用场景
- 审批流程:请假审批、报销审批
- 异常处理:异常处理链
- 日志处理:日志处理链
使用建议
- 多个处理者:使用责任链模式
- 不确定处理者:使用责任链模式
- 单一处理者:直接使用即可
注意事项
⚠️ 责任链模式虽然有用,但要注意:
- 不要让链太长,影响性能
- 确保链不会断裂