当前位置: 首页 > 科技观察

面试官:谈谈您对责任链模型的理解?应用场景?

时间:2023-03-22 16:12:52 科技观察

1。什么是责任链模式?(ChainofResponsibilityPattern)是一个请求需要多个对象来处理,从而避免请求的发送者和接收者之间的耦合关系。这些对象连接成一条链,并沿着这条链传递请求,直到有对象处理它。责任链上的处理器负责处理请求。客户端只需要向责任链发送请求,不需要关心请求的处理细节和请求投递的一般流程。如下:发送方知道它向其发送请求的链中的第一个接收方每个接收方分析请求并处理它或向下传递每个接收方只知道一个其他对象,也就是说,如果它的下一个对象没有任何接收者处理请求,请求将离开链,不同的实现将对此做出不同的响应。2.用法假设我们负责一个卖手机的网站。要求的定义是:正式采购阶段前两轮预定交500元定金和200元定金。公司对已缴纳保证金的用户有一定的优惠政策。规则如下:用户支付500元押金可获赠100元优惠券用户押金满50元可获赠50元优惠券,未支付押金的用户进入正常购买模式。没有优惠券,在库存不足的情况下,可能无法保证购买。下面我们设计几个字段来解释一下它们的含义:orderType:表示订单类型,值为1为存款用户500元,值为2为存款用户为200元,值为3为普通用户.pay:表示用户是否支付押金。值是布尔值true和false。即使用户以500元订金下单,如果不支付订金,也会降级为普通用户购买模式。stock:表示当前用户常用手机的库存数量,已交定金的用户不限。代码实现如下:constorer=function(orderType,pay,stock){if(orderType===1){if(pay===true){console.log('预购500元定金,领100元优惠券')}else{if(库存>0){console.log('普通用户购买,无优惠券')}else{console.log('手机库存不足')}}elseif(orderType===2){if(pay===true){console.log('预购定金200元,送50元优惠券')}else{if(stock>0){console.log('普通用户购买,无优惠券')}else{console.log('手机库存不足')}}}elseif(orderType===3){if(stock>0){console.log('普通用户购买,无优惠券')}else{console.log('手机库存不足')}}}order(1,true,500)//输出:预购500元订金,获得100元优惠券'可以看到上面的代码很多实用if...else,读起来难,维护起来也难。优化的话,可以把500元订单、200元订单和普通购买拆分成三个函数,如下:log('预购订金500元,送100元优惠券')}else{order200(orderType,pay,stock)}}functionorder200(orderType,pay,stock){if(orderType===2&&pay===true){console.log('200元定金预购,送50元优惠券')}else{order200(orderType,pay,stock)}}functionorderNormal(orderType,pay,stock){if(stock>0){console.log('普通用户购买,无优惠券')}else{console.log('手机库存不足')}}//测试订单500(1,true,500)//预购定金500元,赠100元券预购,赠50元券order500(3,false,500)//普通用户购买,无couponorder500(3,false,0)//手机库存不足上述过程中,链中请求传递的顺序非常死板,传递请求的代码与业务代码耦合在一起。如果哪天要加订金300元的预约,必须砍掉之前的链,修改order500函数的代码,在500到200之间加一条新的链,违反了open-closed原则,因此需要灵活改变责任链节点。如果无法处理,则返回一个标识,继续传递下去,如下:入金500元,领100元优惠券')}else{return'nextSuccessor'}}functionorder200(orderType,pay,stock){if(orderType===2&&pay===true){console.log('200元定金预购,送50元优惠券')}else{return'nextSuccessor'}}functionorderNormal(orderType,pay,stock){if(stock>0){console.log('普通用户购买,无优惠券')}else{console.log('Insufficientmobileinventory')}}接下来创建链类,将订单折扣函数传入链类,如下:classChain{construct(fn){this.fn=fnthis.successor=null}setNextSuccessor(successor){returnthis.successor=successor}passRequest(){constres=this.fn.apply(this,arguments)if(res==='nextSuccessor'){returnthis.successor&&this.successor.passRequest.apply(this.successor,arguments)}returnres}}//打包三个order函数constchainOrder500=newChain(order500)constchainOrder200=newChain(order200)constchainOrderNormal=newChain(orderNormal)//指定责任链中的节点位置chainOrder500.setNextSuccessor(chainOrder200)chainOrder200.setNextSuccessor(chainOrderNormal)//最后将请求传递给第一个节点chainOrder500.passRequest(1,true,500)//500元存款预购,获得100元优惠券chainOrder500.passRequest(2),true,500)//预购定金200元,赠50元优惠券chainOrder500.passRequest(3,true,500)//普通用户购买,无优惠券chainOrder500.passRequest(1,false,0)//手机存货不足3.责任链模型更适合应用场景。比如一个任务需要多个对象完成处理,或者代码中有很多if-else判断,比如OA事件审批,分配开发任务等。在JavaScript中,无论是角色链,原型链,还是在DOM节点的事件冒泡中,我们都能发现责任链的影子。使用责任链模式后,链中的节点对象可以灵活拆分重组,添加、删除、修改节点在链中的位置都非常容易。/发布/6844903855348514829