最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 『面试的底气』—— 设计模式之职责链模式(一)|8月更文挑战

    正文概述 掘金(红尘炼心)   2021-08-20   489

    这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战

    前言

    在面试高级前端时,往往会遇到一些关于设计模式的问题,每次都回答不太理想。恰逢8月更文挑战的活动,准备用一个月时间好好理一下关于设计模式方面的知识点,给自己增加点面试的底气。

    定义

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

    用一个生活的例子来理解

    在早高峰的时候,坐公交车往往是个麻烦事,很经常前门挤不上去,只能从后门挤上去。以前的公交车还是有售票员的,从后面上车的人往往会把1块钱往前面递,一直递到售货员手上。

    以上就是一个职责链模式,从上面的例子可以看出职责链模式的最大优点,请求发送者只需要知道链中的第 一个节点(乘客只要把钱递给站在前面的第一个乘客),从而弱化了发送者和一组接收者之间的强联系。如果不使用职责链模式,那么在公交车上,乘客就得先搞清楚谁是售票员,才能把硬币递给他。

    如何实现职责链模式

    职责链模式在于传递,下面用一个例子来说明。

    比如用代码实现一个需求,在某商场,推出一款新产品,只要用户预定,如果缴纳1000元定金,购买时候可以领取500元优惠券,如果缴纳500元定金,购买时候可以领取200元优惠券,如果预定后没有及时缴纳定金,购买时没有优惠券,而且还得看库存有没有货。

    下面用order函数来实现以上需求,其orderType表示订单的类型,pay表示是否支付定金,stock表示库存。

    const order = (orderType, pay, stock) => {
      if (orderType === 1) { // 1000 元定金购买模式
        if (pay === true) { // 已支付定金
          console.log('1000 元定金预购, 得到 100 优惠券');
        } else { // 未支付定金,降级到普通购买模式
          if (stock > 0) { // 用于普通购买的手机还有库存
            console.log('普通购买, 无优惠券');
          } else {
            console.log('手机库存不足');
          }
        }
      }
      else if (orderType === 2) { // 500 元定金购买模式
        if (pay === true) {
          console.log('500 元定金预购, 得到 200 优惠券');
        } else {
          if (stock > 0) {
            console.log('普通购买, 无优惠券');
          } else {
            console.log('手机库存不足');
          }
        }
      }
      else if (orderType === 3) {
        if (stock > 0) {
          console.log('普通购买, 无优惠券');
        } else {
          console.log('手机库存不足');
        }
      }
    };
    order(1, true, 500); // 输出: 1000 元定金预购, 得到 100 优惠券
    

    以上代码虽然实现了需求,但是order函数非常庞大,后续订单的类型越来越多,那么order函数会有很多if else的判断,会越来越难维护。

    下面用职责链模式改造一下,把支付1000元定金、支付500元定金,不支付定金的订单分成三个不同的函数来处理。

    // 预缴1000定金
    const order1000 = (orderType, pay, stock) => {
      if (orderType === 1 && pay === true) {
        console.log('1000 元定金预购, 得到 500 优惠券');
      } else {
        order500(orderType, pay, stock); // 将请求传递给预缴1000定金订单
      }
    };
    // 预缴500定金
    const order500 = (orderType, pay, stock) =>{
      if (orderType === 2 && pay === true) {
        console.log('500 元定金预购, 得到 200 优惠券');
      } else {
        orderNormal(orderType, pay, stock); // 将请求传递给普通订单
      }
    };
    // 普通购买订单
    const orderNormal = (orderType, pay, stock) =>{
      if (stock > 0) {
        console.log('普通购买, 无优惠券');
      } else {
        console.log('手机库存不足');
      }
    };
    order1000(1, true, 500); // 输出:1000 元定金预购, 得到 500 优惠券
    order1000(1, false, 500); // 输出:普通购买, 无优惠券
    order1000(2, true, 500); // 输出:500 元定金预购, 得到 200 优惠券
    order1000(3, false, 500); // 输出:普通购买, 无优惠券
    order1000(3, false, 0); // 输出:手机库存不足
    

    以上把原来的order函数拆成3个互不影响的小函数,并组成一条链条串联起来,这就是一个最简单的职责链模式。

    当然上面实现的职责链模式,职责的传递非常僵硬,而且耦合在业务代码中,比如在order500函数中调用order500的函数。假如预缴500定金换成预缴200定金的销售方案,那是不是得去修改order500函数,这违背了开放-封闭原则。所以不行,得进一步优化。不然就像一根环环相扣打了死结的链条,如果要增加、拆除或者移动一个节点,就必须得先砸烂这根链条。得实现一种灵活可拆分的职责链节点。


    起源地下载网 » 『面试的底气』—— 设计模式之职责链模式(一)|8月更文挑战

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元