你不知道的javascript设计模式(十三) ----职责链模式

前言

        清明节三天假期过去了,一直没有更新,这里先祝大家清明节安好!上一章节我们介绍了享元模式,享元模式分离了对象的内部和外部状态,实现了对象的复用,从而去减少资源上的消耗。这一章我们将继续学习一种新的设计模式,职责链模式。

正文

职责链模式的定义

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止

        职责链模式就是将一些都有可能处理请求的对象连成一条链,将请求逐步传递,直到找到可以处理这个请求的对象为止。
        举个通俗易懂的例子方便大家理解,假设小陈去坐公交车,人实在太多了,来不及自己投币,只能将硬币给旁边的人让他投进硬币箱,然后旁边的人再递给另一个人直到小陈的硬币进硬币箱子。这就是一个很典型的职责链模式。不难发现职责链模式有一个很明显的优点,就是小陈并不需要知道硬币箱的位置,他只需要把硬币给旁边的人就好,其实是弱化了请求发送者与接受者之间的强联系

职责链模式的实现

        一如既往,在实现职责链模式之前,我们先引入一个业务场景,假设一个电商平台购买物品有这么一个规则,有三种购买模式,500押金的购买模式,可以返回100代金劵,200押金的购买模式,可以返回50代金劵,前两者保证库存的提前预定,无押金购买,在库存不存在的时候会买不到,选定购物模式之后,但是如果没付押金就会做降级处理,比如选了500押金模式,但是没付押金就会降级成200押金模式,以此类推。
        很明显的,这个业务场景是很适合使用职责链模式来实现的,三种模式,从500押金模式作为起点,如果不能处理就不断传递下去,在实现之前,我们先分析我们需要实现哪些内容,首先是三种模式,这个不难实现,主要就是orderType, pay, stock三个参数,第一个用来表示购买的类型,pay表示是否按时支付了押金,而stock表示是否库存充足,如果大于0,表示库存充足,如果当前模式不能处理,需要传递给下一个模式,将返回一个标记字符串,我们定义为‘nextSuccessor‘

var order500 = function(orderType, pay, stock) {
	if (orderType === 1 && pay ===true) {
		console.log('500押金,将返回100代金劵');
	} else {
		return 'nextSuccessor';
	}
}
var order200 =  function(orderType, pay, stock) {
	if (orderType === 2 && pay === true) {
		console.log('200押金,将返回50代金劵');
	} else {
		return 'nextSuccessor';
	}
}
var order0 = function(orderType, pay, stock) {
	if (stock > 0) {
		console.log('无押金购买,不返回代金劵');
	} else {
		console.log('库存不足,无法购买');
	}
}

        当然光靠这三个方法是没办法实现链式的请求传递的,我们还需要实现一个链类,把这三个函数包装进职责链中,来处理链式的传递,我们需要为这个链类实现两个方法,设置链子节点,以及将当前进度传给下一个链子节点

var Chain = function(fn) {
	this.fn = fn; // 当前的节点方法
	this.successor = null;	// 下一个节点方法
}

Chain.prototype.setNextSuccessor = function(successor) {
	this.successor = successor;
}
Chain.prototype.passRequest = function() {
	var ret = this.fn.apply(this, arguments);
	if (ret === 'nextSuccessor') {
		return this.successor && this.successor.passRequest.apply(this, arguments);
	}
	return ret;
}

        然后我们就只需要将上面定义的三个函数传入链类进行包装,并且用setNextSuccessor定义好他们的下家就行,最后使用passRequest去调用这个链式即可

基于AOP实现职责链模式

        通常,在 JavaScript 中实现 AOP,都是指把一个函数“动态织入”到另外一个函数之中, 也就是我们俗称的面向切面编程,是一种装饰者模式的体现,上面我们利用定义了链类Chain去实现职责链模式,这里我们可以利用AOP的思想简化上面的职责链模式

Function.prototype.after = function(fn) {
	var self = this;
	return function() {
		var ret = self.apply(this, arguments);
		if (ret === 'nextSuccessor') {
			return fn.apply(this, arguments);
		}
		return ret;
	}
}
var order = order500.after(order200).after(order0);

        这样实现相对上面的更加简单且优雅,但是这种写法将会叠加函数的作用域,如果链式过长,对性能的影响也比较大

小结

        这一章我们学习了职责链模式,职责链弱化了请求发送者与接收者之间的关系,我们只需要知道请求的起点,就可以顺利将请求传递到接收者的位置,同时我们还尝试使用了AOP的编程思想去实现了职责链模式,AOP模式是一种装饰者模式的体现,这样实现的职责链模式更加简单且优雅
       小伙伴们今天的学习就到这里了,如果觉得本文对你有帮助的话,欢迎转发,评论,收藏,点赞!!!
       每天学习进步一点点,就是领先的开始。如果想继续提高,欢迎关注我,或者关注公众号”祯民讲前端“。大量前端技术文章,面试资料,技巧等助你更进一步!
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值