zoukankan      html  css  js  c++  java
  • 设计模式-职责连模式

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

    假设我们负责一个售卖手机的电商网站,需求如下:

    1. 已经支付过 500元定金的用户会收到 100元的商城优惠券
    2. 已经支付200元定金的用户可以收到 50元的优惠券
    3. 没有支付定金的用户只能进入普通购买模式,也就是没有优惠券,且在库存有限的情况下不一定保证能买到

    后端提供了以下三个字段:

    1. orderType :表示订单类型(定金用户或者普通购买用户),code 的值为 1的时候是 500元
      定金用户,为 2的时候是 200元定金用户,为 3的时候是普通购买用户。

    2. pay :表示用户是否已经支付定金,值为 true 或者 false , 虽然用户已经下过 500元定金的订单,但如果他一直没有支付定金,现在只能降级进入普通购买模式。

    3. stock :表示当前用于普通购买的手机库存数量,已经支付过 500 元或者 200 元定金的用
      户不受此限制

    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 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 orderNormal = function(orderType, pay, stock) {
      if (stock > 0) {
        console.log('普通购买,无优惠券');
      } else {
        console.log('手机库存不足');
      }
    };
    
    var order = order500.after(order200).after(orderNormal);
    
    order(1, true, 300); // 输出:500 元定金预购,得到 100 优惠券
    order(2, true, 300); // 输出:200 元定金预购,得到 50 优惠券
    order(1, false, 300); // 输出:普通购买,无优惠券
    

    职责链模式的最大优点就是解耦了请求发送者和 N 个接收者之间的复杂关系。比如上面购买手机的例子,后期如果添加了其他优惠券,只需要在职责链里再添加一个after函数,逻辑很清晰。

    职责链模式使得程序中多了一些节点对象,可能在某一次的请求传递过程中,大部分
    节点并没有起到实质性的作用,它们的作用仅仅是让请求传递下去,从性能方面考虑,要避
    免过长的职责链带来的性能损耗

    常用网站: SegmentFault | GitHub | 掘金社区
  • 相关阅读:
    AngularJS启动过程分析
    mongodb 基本用法大全
    bitbucket工程改名导致 repository does not exist. fatal: Could not read from remote repository.
    分散的配置文件VS集中的注册表
    让browserify接收命令行参数,在打包时parse yml配置文件
    vscode下ts-node传入cli参数
    d3 .each()
    d3选择全部子节点,不知道class和id
    d3 parse字符串形式的xml svg and append to element
    在浏览器端用es6,babel+browserify打包
  • 原文地址:https://www.cnblogs.com/yesyes/p/15375974.html
Copyright © 2011-2022 走看看