设计模式-策略模式

策略模式指的是定义一系列算法,并且把它们封装起来,将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外。策略模式的目的是将算法和使用算法的方式隔离开来。

下面以计算购买的促销衣服为例。双11的时候,各个商家都在打折促销,衣服分为A,B,C三类产品,对应的折扣分别为9折,8折,7折。假设财务要求我们提供一段代码,来方便我们计算最终价格。

1. 最初的代码实现

const calculatePrice = (type, price) => {
  if (type === 'A') {
    return price * 0.9
  }
  if (type === 'B') {
    return price * 0.8
  }
  if (type === 'C') {
    return price * 0.7
  }
}

calculatePrice('A', 300) // 270
calculatePrice('C', 500) // 350

可以发现这段代码很简单,但是存在着显而易见的缺点。函数包含了许多if...else语句,且需要罗列出所有情况。当我们新增一个类型的时候,就需要深入代码内部去修改,这是违反开放-封闭原则的。且代码的复用性差。

2. 使用组合函数重构代码

const clothesA = (price) => {
  return price * 0.9
}

const clothesB = (price) => {
  return price * 0.8
}

const clothesC = (price) => {
  return price * 0.7
}

const calculatePrice = (type, price) => {
  if (type === 'A') {
    return clothesA(price)
  }
  if (type === 'B') {
    return clothesB(price)
  }
  if (type === 'C') {
    return clothesC(price)
  }
}

目前程序得到了一定的改善,但是改善十分有限,我们依然没有解决最重要的问题,就是当程序越来越庞大的时候,系统变化缺乏弹性。

3. 使用策略模式进行重构

function clothesA () {}
clothesA.prototype.calculate = (price) => {
  return price * 0.9
}

function clothesB () {}
clothesB.prototype.calculate = (price) => {
  return price * 0.8
}

function clothesC () {}
clothesC.prototype.calculate = (price) => {
  return price * 0.7
}

function Price () {
  this.price = null
  this.strategy = null
}

Price.prototype.setPrice = (price) => {
  this.price = price
}

Price.prototype.setStrategy = (strategy) => {
  this.strategy = strategy
}

Price.prototype.getPrice = () => {
  return this.strategy.calculate(this.price)
}

const price = new Price()
price.setPrice(300)
price.setStrategy(clothesA)
price.getPrice()

4. JavaScript的策略模式

const strategies = {
  A: (price) => price * 0.9,
  B: (price) => price * 0.8,
  C: (price) => price * 0.7,
}

const calculatePrice = (type, price) => {
  return strategies[type](price)
}

5. 表单校验

在一个web项目中,注册,登录,修改用户信息等功能都离不开表单校验。在用户输入的过程中,进行一些数据校验,在把用户数据交给后台前,进行第一步的把关,可以避免提交不合法数据的一些网络开销。下面是策略模式在表单校验中的实战。

var strategies = {
  // 不为空
  isNonEmpty: function (value, errorMsg) {
    if (value === '') {
      return errorMsg
    }
  },
  // 限制最小长度
  minLength: function (value, length, errorMsg) {
    if (value.length < length) {
      return errorMsg
    }
  },
  // 手机号码格式或电话号码格式
  isMobile: function (value, errorMsg) {
    if (!/(^1[3|5|8][0-9]{9}$)/.test(value) && !/^0\d{2,3}-?\d{7,8}$/.test(value)) {
      return errorMsg
    }
  },
  isImage: function (type, errorMsg) {
    type = type.toLowerCase().replace(/jpg/i, 'jpeg')
    var r = type.match(/png|jpeg|bmp|gif/);
    
    if (!r) {
      return errorMsg
    }
  }
}

class Validator {
  constructor () {
    this.cache = []
  }

  add (dom, rule, errorMsg) {
    var ary = rule.split(':')
    this.cache.push(function () {
      var strategy = ary.shift()
      ary.unshift(dom.value)
      ary.push(errorMsg)
      return strategies[strategy].apply(dom, ary)
    })
  }

  start () {
    for (var i = 0, validatorFunc; i < this.cache.length; i++) {
      var validatorFunc = this.cache[i]
      var msg = validatorFunc()
      if (msg) {
        return msg
      }
    }
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容