js 设计模式——策略模式

策略模式(Strategy)

定义:将定义的一组算法封装起来,使其相互之间可以替换。封装的算法具有一定的独立性,不会随客户端的变化而变化

废话不多说,先来个例子

// 例如要写一个计算两个数加减乘除的方法,会有人这么写
countNum(type, num1, num2) {
  if(type === 'add'){
    return num1 + num2
  } else if(type === 'subtract'){
    return num1 - num2
  } else if(type === 'multiply'){
    return num1 * num2
  } else {
    return num1 / num2
  }
}

countNum('add', 9, 3)       // 12
countNum('subtract', 9, 3)  // 6
countNum('multiply', 9, 3)  // 27
countNum('', 9, 3)          // 3

上面的例子,一定会有人这么写的,你要说没有我也没办法(~ ̄▽ ̄)~,这样写首先不利于维护,其实也不好方便扩展

改进一下:

let countNum = {
  add(num1, num2) {
    return num1 + num2
  },
  subtract(num1, num2) {
    return num1 - num2
  },
  multiply(num1, num2) {
    return num1 * num2
  },
  divide(num1, num2) {
    return num1 / num2
  },
}

countNum.add(9, 3)      // 12
countNum.subtract(9, 3) // 6
countNum.multiply(9, 3) // 27
countNum.divide(9, 3)   // 3

上面的例子就可以看成是一个策略模式

now,现在有个需求,快要圣诞节,所以咧,超市中一部分商品8折出售,一部分9折出售,等到元旦还要搞大事,普通用户满100返30,VIP用户满100返50,用策略模式来实现

// 定义一个策略对象
let priceceStrategy = function(){
  // 内部算法对象
  let strategy = {
    return30(price){
      return price + parseInt(price / 100) * 30
    },
    return50(price){
      return price + parseInt(price / 100) * 50
    },
    price80(price){
      return price  * 80 / 100
    },
    price90(price){
      return price  * 90 / 100
    }
  }
  // 策略方法调用接口
  return {
    strategyFunction(type, price) {
      return strategy[type] && strategy[type](price)
    },
    // 添加算法
    addStrategy(type, fn){
      strategy[type] = fn
    }
  }
}()

priceceStrategy.strategyFunction('return30', 100)   // 130
priceceStrategy.strategyFunction('return50', 100)   // 150
priceceStrategy.strategyFunction('price80', 100)    // 80
priceceStrategy.strategyFunction('price90', 100)    // 90
// 添加一个算法
priceceStrategy.addStrategy('return70', (price) => {
  return price + parseInt(price / 100) * 70
})
console.log(priceceStrategy.strategyFunction('return70', 100))  // 170

还有我们的表单验证也可以使用策略模式

// 定义一个策略对象
let inputStrategy = function(){
  // 内部算法对象
  let strategy = {
    notNull(value){
      return /\s+/.test(value) ? '请输入内容' : ''
    },
    number(value){
      return /^[0-9]+(\.[0-9]+)?$/.test(value) ? '' : '请输入数字'
    }
  }
  // 策略方法调用接口
  return {
    check(type, value) {
      // 去除空白符
      value = value.replace(/^\s+|\s+$/g, '')
      return strategy[type] && strategy[type](value)
    },
    // 添加策略
    addStrategy(type, fn){
      strategy[type] = fn
    }
  }
}()

// 添加算法
inputStrategy.addStrategy('nickName', (value) => {
  return /^[a-zA-Z]\w{3,7}$/.test(value) ? '' : '请输入4-8为昵称'
})

总结

策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响 到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。

策略模式中的三个对象:

  • 环境对象:该类中实现了对抽象策略中定义的接口或者抽象类的引用。
  • 抽象策略对象:它可由接口或抽象类来实现。
  • 具体策略对象:它封装了实现同不功能的不同算法。

利用策略模式构建应用程序,可以根据用户配置等内容,选择不同有算法来实现应用程序的功能。具体的选择有环境对象来完成。采用这种方式可以避免由于使用条件语句而带来的代码混乱,提高应用程序的灵活性与条理性。

优点:
  1. 优化多重条件判断,采用策略模式是的算法更利于维护
  2. 可扩展性,策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
  3. 策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。
缺点:
  1. 由于选择哪种算法的决定权在用户,所以对用户来说就必须了解每种算法的实现。
  2. 由于每种算法间相互独立,这样对于一些复杂的算法处理相同逻辑的部分无法实现共享,这就会造成一些资源的浪费。

原文地址:https://www.cnblogs.com/loveyt/p/11057884.html

时间: 2024-07-30 19:47:12

js 设计模式——策略模式的相关文章

JS设计模式——策略模式

核心:定义一些列的算法(逻辑)封装起来,并且它们是平等关系可以相互替换js中的策略模式关键字:策略和业务分离 (一)基本实现 常见代码: function playGame(gameName){ let str; if(gameName == 'footBall'){ str = '不喜欢玩足球' }else if(method == 'basketball'){ str = '不喜欢玩蓝球' }else if(method == 'pingpang'){ str = '不喜欢玩乒乓' }els

设计模式 - 策略模式(Strategy Pattern) 具体解释

策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全部, 禁止转载, 如有须要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间能够相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族须要常常扩展新的功能, 为了使用父类比較灵活的加入子类, 把父类的行为写成接口(interface)的形式; 使用set()方法

设计模式 - 策略模式(Strategy Pattern) 详解

策略模式(Strategy Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权所有, 禁止转载, 如有需要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间可以相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族需要经常扩展新的功能, 为了使用父类比较灵活的添加子类, 把父类的行为写成接口(interface)的形式; 使用set()方法,

2.大话设计模式-策略模式

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DesignModel 8 { 9 /// <summary> 10 /// 策略模式 11 /// </summary> 12 public class TacticsModel 13 { 14 //对于

设计模式---策略模式Strategy(对象行为型)

1. 概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理. 2. 应用场景 (1)多个类只区别在表现行为不同,在运行时动态选择具体要执行的行为. (2)需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现. (3)对客户隐藏具体策略(算法)的实现细节,彼此完全独立. 3. 示例 出行旅游:我们可以有几个策略可以考虑:可

设计模式—策略模式

什么是策略模式? 策略模式定义了算法家族,分别封装起来,让它们之间能够相互替换,此模式让算法的变化不会影响到使用算法 的客户. 策略模式是一种定义一系列算法的方法,从概念上看全部这些算法完毕的都是同样的工作,仅仅是实现不同,它可 以以同样的方式调用全部的算法,降低了各种算法类与使用算法之间的耦合. 策略模式的长处? (1)策略模式的Strategy类层为Context类定义了一系列的可供重用的算法和行为.继承有助于析取出这些算法 的公共功能. (2)简化了单元測试(每一个算法都有自己的类,能够通

说说设计模式~策略模式(Strategy)

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.而对于客户端(UI)来说,可以通过IOC再配合工厂模块,实现动态策略的切换,策略模块通常于一个抽象策略对象(interface or abstract class),多个具体策略对象(implement class )和一个调用策略的入口组成. 何时能用到它? 对于UI来说,可能一个功能会有多种实现方式,而且实现方式可能还会有扩展,例如,一个ATM机,它目前支持工行,建行,家行,以后可能又出现了占占银行,而这时,ATM

head first 设计模式 策略模式

HEAD FIRST:策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 设计模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.本模式使得算法可独立于它的客户而变化. 大话设计模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 使用这个模式的原因: 用许多的算法对一类进行计算.那么如果把这些算法强行编码到这个类当中.其实是不可取的.因为很多时候下不同的情况下使用不同的算

15. 星际争霸之php设计模式--策略模式

题记==============================================================================本php设计模式专辑来源于博客(jymoz.com),现在已经访问不了了,这一系列文章是我找了很久才找到完整的,感谢作者jymoz的辛苦付出哦! 本文地址:http://www.cnblogs.com/davidhhuan/p/4248199.html============================================