责任链模式
责任链模式
-
定义
Avoid coupling the sender of request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it;
让多个对象有机会处理一个请求,从而避免在请求的发送者和它的接受者之间形成耦合。将命令的接受者链接起来并且在这条链接上传递命令,直到有一个对象处理完毕它。
-
分析
从定义中可以看出,使用责任链模式是为了解耦请求的发送者和接受者,方法也很容易理解,就是把所有请求的接受者串在一条链上(这条链上的节点都承担处理某个请求的责任,所以就叫它责任链好了),然后便可以把各种各样的请求投入责任链中,请求在责任链中走一趟,出来时(责任链处理完毕)就有结果了~;
这么做的好处显而易见:从请求依赖处理者变为请求依赖责任链;如果在一个场景中的请求万年不变,那么对应的处理者即使略有变化(处理需求变化了嘛),那么通过接口也可以将接受者的“变化”控制在合理的范围,问题在于,如果这个场景可以发出多种请求,在只提供一个接受者的情况下,接受者内部就得判断吧,到底是哪一种请求,自然用到多个if-else;一旦请求数目增加,那么接受者内部就得相应变化(坏的设计!);在提供多个接受者的情况下,请求者为了发出明确命令,也少不了条件判断吧,if-else只是换了一个地方,但仍旧存在;
举个栗子,书店里的书以前有两种:原价书、打折书,计价系统通过判断书的promotion Type Id(0-原价;1-打折)来返回一个最后的价格;也就是说if-else在接受者这里。现在增加了一种赠送书;那么计价系统里的if-else自然要多一个了。这就不好了,都修改源代码了,说好的对修改关闭呢?(现实书店系统应该不会这样设计的);
其实,责任链模式没有消除if-else, 只是将其分散到各个请求的接受者当中了;当然,判别的目的发生了变化:从找到一个合适的接受者变为判断自己能否处理;
那么责任链模式可否有缺点?嗯嗯,有利必有弊嘛,责任链的缺点便是如果责任链过长,那么一个请求从头传到尾,性能便是一个非常严重的问题,而且调试起来也不方便;
-
实现
核心是单向链表(责任链)的建立,其节点为一个个请求的处理者;既然处理者要判断它是否能处理该命令,那么还应该有一个相互识别的id(类似promotion type id);
-
与面向对象程序设计原则的关系
- 单一职责原则:从接受者角度来看,自己能处理就处理,不能处理就将其传递给下一个接受者,职责鲜明,而不需要承担“找到处理方式”这一职责;
- 里氏替换原则:责任链中节点继承自相同父类,可以自由替换节点;
- 开闭原则:这个体现最明显了,当出现新的请求状态时就添加一个对应的Handler到责任链中即可,无需修改原来代码;
- 迪米特原则:这个也可以有,request再也不依赖于各个handler了,一条责任链里什么都有;对于handler也是一样,自己能处理就处理,不能就把request交给有缘的handler;