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为昵称'
})
总结
策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响 到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
策略模式中的三个对象:
- 环境对象:该类中实现了对抽象策略中定义的接口或者抽象类的引用。
- 抽象策略对象:它可由接口或抽象类来实现。
- 具体策略对象:它封装了实现同不功能的不同算法。
利用策略模式构建应用程序,可以根据用户配置等内容,选择不同有算法来实现应用程序的功能。具体的选择有环境对象来完成。采用这种方式可以避免由于使用条件语句而带来的代码混乱,提高应用程序的灵活性与条理性。
优点:
- 优化多重条件判断,采用策略模式是的算法更利于维护
- 可扩展性,策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
- 策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。
缺点:
- 由于选择哪种算法的决定权在用户,所以对用户来说就必须了解每种算法的实现。
- 由于每种算法间相互独立,这样对于一些复杂的算法处理相同逻辑的部分无法实现共享,这就会造成一些资源的浪费。
js 设计模式——策略模式的更多相关文章
- [转]js设计模式-策略模式
在程序设计中,常常遇到类似的情况,要实现某一个功能有多种方案可以选择.比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是本文 ...
- JS设计模式——策略模式
设计模式高大上,业务代码用不上...平时用不上我们就可以忽略了吗? 非也,就像面试造火箭,工作拧螺丝一样.万一我们公司哪天要造火箭了,你得立马能上手. 同时,有些复杂的业务代码也可以用设计模式的思想去 ...
- js设计模式--策略模式
策略模式: 定义了一系列的算法,把他们封装起来,是它们之间可以互相替换,此模式不会影响到使用算法的客户. 回忆下jquery里的animate方法: $( div ).animate( {" ...
- 15. 星际争霸之php设计模式--策略模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)
[.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...
- linkin大话设计模式--策略模式
linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi] 策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...
- [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)
[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...
- JAVA 设计模式 策略模式
用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构
- 设计模式-策略模式(Strategy Model)
1.概述 在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能. 如在人物比较排序的实现中,我们有 ...
随机推荐
- Python的日志功能
python自带的logging是日志处理模块,可以记录日志,并输出到控制台和文件等.日志分5个级别:DEBUG:调试信息,权重10INFO:一般信息,权重20WARNING:警告信息,权重30ERR ...
- linux基础学习(一)常用命令:date、pwd、cd、cal、who、wc等等
目录 @(基础命令) Tab键是linux系统中最重要的键之一了,它的功能是命令自动补全== [root@localhost ~]#date 1.用于显示当前的日期和时间 2/用于显示当前的日历 [r ...
- greenlet实现协程
#greenlet 1 import time from greenlet import greenlet # greenlet可以实现一个自行调度的微线程 def work1(): while Tr ...
- SSDB数据库笔记
目录 环境 配置文件 启动服务器 客户端 SSDB:一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis. 参考文献: SSDB官网 环境 win10 下 wsl 环境 ubun ...
- 《大话处理器》Cache一致性协议之MESI【转】
转自:https://blog.csdn.net/muxiqingyang/article/details/6615199 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载 ...
- 具名插槽 slot (二)
slot 是父组件与子组件的通信方式可以将父组件的内容显示在子组件当中或者说可以将 让你封装的组件变的更加的灵活,强壮! 在子组件中 通过为多个slot进行命名.来接受父组件中的不同内容的数据 这 ...
- python获取某路径下,某种特定类型的文件名称,os.walk(路径)生成器;os.listdir(路径),os.path.splitext(名称),os.path.join(路径,名称),os.path.isdir(路径\名称)
#获取某文件夹下制定类型文件# import os# def filep(fp):# l=[]# a=os.walk(fp) #生成器# for nowp,sonp,oth in a: #当前目录,子 ...
- tomcat快速入门
简介 Tomcat 是什么 Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet 和 JSP 的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理 ...
- 洛谷 P4316 绿豆蛙的归宿
洛谷 P4316 绿豆蛙的归宿 洛谷传送门 题目背景 随着新版百度空间的上线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 题目描述 给出一个有向无环图,起点为1终点为N,每条边都有一个长度, ...
- layer icon样式及 一些弹框使用方法
一.layer的icon样式 以上样式测试代码: layer.confirm('icon测试', {icon: 1, title:'提示'}, function(index){ //do someth ...