
文章插图
职责链模式的定义是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止 。职责链模式的名字非常形象,一系列可能会处理请求的对象被连接成一条链,请求在这些对象之间依次传递,直到遇到一个可以处理它的对象,把这些对象称为链中的节点 。
基本流程职责连是由多个不同的对象组成的,有发送者跟接收者,分别负责信息的发送跟接收,其中,链中第一个对象是 职责连是由多个不同的对象组成的,发送者是发送请求的对象,接收者接收请求并且对其进行处理或传递的对象 。基本流程如下:
- 发送者知道链中的第一个接收者,它向这个接收者发送该请求 。
- 每一个接收者都对请求进行分析,然后要么处理它,要么它往下传递 。
- 每一个接收者知道其他的对象只有一个,即它在链中的下家(successor) 。
- 如果没有任何接收者处理请求,那么请求会从链中离开 。
实战职责链模式的例子在现实中并不难找到,以下就是两个常见的跟职责链模式有关的场景
如果早高峰能顺利挤上公交车的话,那么估计这一天都会过得很开心 。因为公交车上人实在太多了,经常上车后却找不到售票员在哪,所以只好把两块钱硬币往前面递 。除非运气够好,站在前面的第一个人就是售票员,否则,硬币通常要在N个人手上传递,才能最终到达售票员的手里
中学时代的期末考试,如果平时不太老实,考试时就会被安排在第一个位置 。遇到不会答的题目,就把题目编号写在小纸条上往后传递,坐在后面的同学如果也不会答,他就会把这张小纸条继续递给他后面的人
从这两个例子中,很容易找到职责链模式的最大优点:请求发送者只需要知道链中的第一个节点,从而弱化了发送者和一组接收者之间的强联系 。如果不使用职责链模式,那么在公交车上,就得先搞清楚谁是售票员,才能把硬币递给他 。同样,在期末考试中,也许就要先了解同学中有哪些可以解答这道题
假设负责一个售卖手机的电商网站,经过分别交纳500元定金和200元定金的两轮预定后(订单已在此时生成),现在已经到了正式购买的阶段 。公司针对支付过定金的用户有一定的优惠政策 。在正式购买后,已经支付过500元定金的用户会收到100元的商城优惠券,200元定金的用户可以收到50元的优惠券,而之前没有支付定金的用户只能进入普通购买模式,也就是没有优惠券,且在库存有限的情况下不一定保证能买到
订单页面是php吐出的模板,在页面加载之初,PHP会传递给页面几个字段
1、orderType:表示订单类型(定金用户或者普通购买用户),code的值为1的时候是500元定金用户,为2的时候是200元定金用户,为3的时候是普通购买用户
2、pay:表示用户是否已经支付定金,值为true或者false 。虽然用户已经下过500元定金的订单,但如果他一直没有支付定金,现在只能降级进入普通购买模式
3、stock:表示当前用于普通购买的手机库存数量,已经支付过500元或者200元定金的用户不受此限制
下面把这个流程写成代码:

文章插图
虽然得到了意料中的运行结果,但这远远算不上一段值得夸奖的代码 。order函数不仅巨大到难以阅读,而且需要经常进行修改 。虽然目前项目能正常运行,但接下来的维护工作无疑是个梦魇
职责链模式重构
现在我们职责链模式重构这段代码,先把500元订单、200元订单以及普通购买分成3个函数 。接下来把orderType、pay、stock这3个字段当作参数传递给500元订单函数,如果该函数不符合处理条件,则把这个请求传递给后面的200元订单函数,如果200元订单函数依然不能处理该请求,则继续传递请求给普通购买函数,代码如下:

文章插图
可以看到,执行结果和前面那个巨大的order函数完全一样,但是代码的结构已经清晰了很多,把一个大函数拆分了3个小函数,去掉了许多嵌套的条件分支语句
推荐阅读
- JavaScript命名空间常用方法
- Strategy Pattern JavaScript设计模式之策略模式
- JavaScript中变量和作用域
- JavaScript都得知道这3个数组方法
- javascript 创建对象常用几种方式
- JavaScript轻应用PWA实践全过程
- 8 个提高 JavaScript 性能的方法
- JavaScript获取json中key所对应的value值的简单方法
- JavaScript中执行上下文和执行栈
- 不可不知的 5 种 JavaScript 代码编辑器
