:::info 责任链模式是一个相对比较简单的模式,它的名字已经非常好的暗示了其工作原理。每个处理器互相首尾连接在一起成为一条链,然后任务顺着这条链往下传,直到被某个处理器处理掉。 :::
定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
使用场景
一个请求需要被多个对象中的某一个处理,但是到底是哪个对象必须在运行时根据条件决定。
UML
角色结构
- Handler:所有处理器类的接口
ConcreteHandler :具体的处理器类,其实现Handler接口,有多少个处理器,就定义多少个这样的类
优点
是命令发出者与执行者解耦。
-
缺点
不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。
业务场景
二狗提出买一台Mac笔记本电脑。这花钱的事需要领导审批,而每个领导权限不一样,能够审批的最大金额有限制。二狗首先肯定是向自己的小组leader提出,但是由于金额太大,超出了他的审批权限。于是小组领导就去找自己的领导,部门经理,但是部门经理也权限不够,最后到了CFO那里…
王二狗遇到的情况就非常适合使用责任链模式。二狗这个预算申请的请求,事先不知道会由哪层领导处理,而各层领导的审批职责就好像铁链一样连接在一起,一个预算请求沿着这条链一直往上传… 让我们用代码来实现上面的场景吧。
代码示例
BudgetHandler 一个所有处理器都要实现的接口
public interface BudgetHandler {/*** 设置下一个处理器*/void setNextHandler(BudgetHandler nextHandler);/*** 负责处理请求*/boolean handle(int amount);}
GroupLeader 小组领导类
public class GroupLeader implements BudgetHandler {private BudgetHandler nextHandler;@Overridepublic void setNextHandler(BudgetHandler nextHandler) {this.nextHandler = nextHandler;}/*** 小组领导最多可以批1000块以下的预算,再多了就批不了了。*/@Overridepublic boolean handle(int amount) {Objects.requireNonNull(nextHandler);if(amount<1000){System.out.println("小钱,批了!");return true;}System.out.println(String.format("%d超出GroupLeader权限,请更高级管理层批复",amount));return nextHandler.handle(amount);}}
Manager 部门经理类
public class Manager implements BudgetHandler {private BudgetHandler nextHandler;@Overridepublic void setNextHandler(BudgetHandler nextHandler) {this.nextHandler = nextHandler;}/*** 经理最多可以批5000块以下的预算*/@Overridepublic boolean handle(int amount) {Objects.requireNonNull(nextHandler);if (amount < 5000) {System.out.println("小于2000块,我这个经理可以决定:同意!");return true;}System.out.println(String.format("%d超出Manager权限,请更高级管理层批复", amount));return nextHandler.handle(amount);}}
CFO 首席财务执行官
public class CFO implements BudgetHandler {private BudgetHandler nextHandler;@Overridepublic void setNextHandler(BudgetHandler nextHandler) {this.nextHandler = nextHandler;}@Overridepublic boolean handle(int amount) {if (amount < 50000) {System.out.println("CFO同意,希望你再接再厉,为公司做出更大的贡献。");return true;}if (nextHandler != null) {return nextHandler.handle(amount);}//已经没有更高级的管理层来处理了System.out.println(String.format("%d太多了,回去好好看看能不能缩减一下", amount));return false;}}
Client
每个处理器都建好了,那么怎么才能让他们连成链呢?
这里可以让客户端来组织,也可以初始化的时候每一级处理器都指定自己的下一级。
public class Client {public static void main(String[] args) {GroupLeader leader = new GroupLeader();Manager manager = new Manager();CFO cfo = new CFO();leader.setNextHandler(manager);manager.setNextHandler(cfo);System.out.println(String.format("领导您好:由于开发需求,需要购买一台Mac笔记本电脑,预算为%d 望领导批准", 95000));if (leader.handle(25000)) {System.out.println("谢谢领导");} else {System.out.println("巧妇难为无米之炊,只能划船了...");}}}
输出
领导您好:由于开发需求,需要购买一台Mac笔记本电脑,预算为95000 望领导批准25000超出GroupLeader权限,请更高级管理层批复25000超出Manager权限,请更高级管理层批复CFO同意,希望你再接再厉,为公司做出更大的贡献。谢谢领导
