Skip to content

Latest commit

 

History

History
130 lines (109 loc) · 2.76 KB

策略模式.md

File metadata and controls

130 lines (109 loc) · 2.76 KB
title date tags categories
策略模式
2020-05-07
设计模式
前端基础

::: warning 场景: 经常看斗鱼直播的朋友们可能会知道, 很多主播发起的抽奖活动都是有条件的, 比如带粉丝牌的, 点击关注的, 粉丝牌等级多少级以上才可以抽奖。现在 PDD 发起了一个抽奖但是需要粉丝牌等级 5 级,关注主播,并且粉丝的等级要 20 级以上的女用户才可以参与抽奖。那么这时候有的同学想这还不简单,唰唰唰的撸完了代码: :::

function checkAuth(data) {
  if(data.fanCard < 5) {
    return false;
  }

  if(!data.focus) {
    return false;
  }

  if(data.grade < 20 ){
    return false;
  }

  if(data.sex !== 'woman') {
    return false;
  }

 ...
}

那么这段代码又什么问题呢?我们来思考一下这个场景比如其他主播也有抽奖活动,但是要求不一样。比如大司马抽奖条件是只需要关注了即可抽奖。五五开抽奖条件是关注了并且是女观众就可以抽奖。那么如果继续用 if else 来整,那么岂不是很 low,很麻烦。因此这段代码就衍生出了以下问题:

  1. checkAuth 函数会 💥,会变得非常的庞大
  2. 策略项无法复用
  3. 违反开闭原则

那么我们如何解决这些问题呢?答案是策略模式:

// 定义策略
var strategies = {
  checkFanCard: function(value) {
    if (data.fanCard < 5) {
      return false;
    }
    return true;
  },
  checkFocus: function(value) {
    if (!data.focus) {
      return false;
    }
    return true;
  },
  checkGrade: function(value) {
    if (data.grade < 20) {
      return false;
    }
    return true;
  },
  checkSex: function(value) {
    if (data.sex !== 'woman') {
      return false;
    }
    return true;
  },
};

// 设置校验规则
var Validator = function() {
  this.cache = [];

  this.add = function(value, method) {
    this.cache.push(() => strategies[method](value));
  };

  this.check = function() {
    for (let index = 0; index < this.cache.length; index++) {
      let validate = this.cache[index];
      var data = validate();
      if (!data) return false;
    }
    return true;
  };
};

大司马

var DSM = function() {
  var validator = new Validator();
  var auth = {
    focus: true,
  };
  validator.add(auth, 'checkFocus');
  var check = validator.check();
  return check;
};

White

var White = function() {
  var validator = new Validator();
  var auth = {
    focus: true,
    sex: 'woman'
  };
  validator.add(auth, 'checkFocus');
  validator.add(auth, 'checkSex');
  var check = validator.check();
  return check;
};

总结:

什么时候可以用策略模式

::: tip

  1. 各个判断条件可以独立并且可以复用
  2. 策略需要灵活组合 :::