在JavaScript中理解策略模式
栏目: JavaScript · 发布时间: 5年前
内容简介:设计模式是: 在面向对象软件过程中针对特定问题的简洁而优雅的解决方案. 通过对封装、继承、多态、组合等技术的反复利用, 提炼出可重复使用面向对象的设计技巧.JavaScript 可以模拟实现传统面向对象语言的设计模式. 事实上也的确如此, 好多的代码 demo 都是沿着这个思路分析的. 看完后心里不免有种一万头 在奔腾, 还顺便飘来了六个字, 走(qu)你(de), 设计模式.然而仅仅是生搬硬套, 未免会失去 JavaScript 的灵活性. 不如溯本求源, 看看这些设计模式到底在传达什么, 然后遵循此点
设计模式是: 在面向对象软件过程中针对特定问题的简洁而优雅的解决方案. 通过对封装、继承、多态、组合等技术的反复利用, 提炼出可重复使用面向对象的设计技巧.
JavaScript 可以模拟实现传统面向对象语言的设计模式. 事实上也的确如此, 好多的代码 demo 都是沿着这个思路分析的. 看完后心里不免有种一万头 在奔腾, 还顺便飘来了六个字, 走(qu)你(de), 设计模式.
然而仅仅是生搬硬套, 未免会失去 JavaScript 的灵活性. 不如溯本求源, 看看这些 设计模式 到底在传达什么, 然后遵循此点.
策略模式定义
策略模式 : 定义一系列的算法, 把它们一个个封装起来, 并且使它们可以相互替换.
字面意思, 就是定义封装多种算法, 且各个算法相互独立. 当然, 也不仅仅是算法. 只要定义一些规则, 经处理后输出我们想要的结果就成. 在此我们称单个封装后的算法为一个策略. 一系列封装后的算法称为一组策略.
一个基于策略模式的程序至少由两部分组成. 第一部分是一组策略类, 策略类封装了具体的算法, 并负责具体的计算过程. 第二部分是环境类 Context, Context 接受客户的请求, 随后把请求委托给某一个策略类.
这是面向传统面向对象语言中的说法. 在面向对象思想中, 通过对组合, 多态等技术的使用来实现一个策略模式. 在 JavaScript 中, 对于一个简单的需求来说, 这么做就有点大材小用了.
所以, 上面的那句话, 我们换种说法就是, 策略模式需要至少两部分, 一部分是保存着一组策略. 另一部分则是如何分配这些策略, 即如何把请求委托给某个/些策略. 其实这也是策略模式的目的, 将算法的使用与算法的实现分离.
评级
快到年底了, 公司打算制定一个标准用来给员工评级发福利.
考核项目等级 | 甲 | 乙 | 丙 |
---|---|---|---|
A | 100>a>=90 | 90>a>=80 | 80>a>=70 |
B | 100>b>=90 | 90>b>=80 | 80>b>=70 |
以A、B考核项目来评定甲乙丙等级.
现有考核人员:
考核项目考核人 | person_1 | person_2 | person_3 |
---|---|---|---|
A | 80 | 93 | 92 |
B | 85 | 70 | 90 |
const persons = [ { A: 80, B: 85 }, { A: 93, B: 70 }, { A: 92, B: 90 } ]
在策略模式中一部分, 我们提到的分配策略. 要想分配策略, 首先就要知道所有的策略, 只有这样我们才能针对性的委托给某个/些策略. 这, 也是策略模式的一个缺点.
常规操作
甲乙丙等级对 A、B 的分值要求是不一样的. 所以我们可以这么做:
function rating(person) { let a = person.A; let b = person.B; if (a >= 90 && b >= 90) { return '甲'; } else if (a >= 80 && b >= 80) { return '乙'; } else if (a >= 70 && b >= 70) { return '丙' } else { console.log('凭啥级, 还不赶紧卷铺走人'); } } persons.forEach(person => { person.rate = rating(person); }) // > persons // [ { A: 80, B: 85, rate: '乙' }, // { A: 93, B: 70, rate: '丙' }, // { A: 92, B: 90, rate: '甲' } ]
策略模式下的评级
如果换成策略模式, 第一部分就是保存一组策略. 现在我们以甲乙丙三种定级标准来制定三种策略, 用对象来存贮策略. 考虑到以后可能有 D、E、F 等考核项目的存在, 我们稍微改一下:
const strategies = { '甲': (person, items) => { const boolean = items.every(item => { return person[item] >= 90; }); if (boolean) return '甲'; }, '乙': (person, items) => { const boolean = items.every(item => { return person[item] >= 80; }); if (boolean) return '乙'; }, '丙': (person, items) => { const boolean = items.every(item => { return person[item] >= 70; }); if (boolean) return '丙'; } }
策略就制定好了. 对象的键对应着策略的名称, 对象的值对应着策略的实现.然而, 我们发现, 任何一个策略都不能单独完成等级的评定.
可是, 我们有说一组策略只能选择其中一个么? 为了达成某个目的, 策略组封装了一组相互独立平等替换的策略. 一个策略不行, 那就组合呗. 这也是策略模式另一部分存在的意义, 即如何分配策略.
function rating(person, items) { return strategies['甲'](person, items) || strategies['乙'](person, items) || strategies['丙'](person, items) } persons.forEach(person => { person.rate = rating(person, ['A', 'B']) }) // > persons // [ { A: 80, B: 85, rate: '乙' }, // { A: 93, B: 70, rate: '丙' }, // { A: 92, B: 90, rate: '甲' } ]
逻辑的转移
所有的设计模式都遵循一条原则. 即 “找出程序中变化的地方, 并将变化封装起来”.
将不变的隔离开来, 变化的封装起来. 策略模式中, 策略组对应着程序中不变的地方. 将策略组制定好存贮起来, 然后想着如何去分配使用策略.
当然, 如何制定策略和如何分配策略之间的关系十分紧密, 可以说两者相互影响.
再次看看制定的策略, “找出程序中变化的地方, 并将变化封装起来”, 我们可以再次改造一下.
const strategies = { '甲': 90, '乙': 80, '丙': 70, } function rating(person, items) { const level = value => { return (person, items) => { const boolean = items.every(item => { return person[item] >= strategies[value]; }); if (boolean) return value; } } return level('甲')(person, items) || level('乙')(person, items) || level('丙')(person, items) } persons.forEach(person => { person.rate = rating(person, ['A', 'B']) }) // > persons // [ { A: 80, B: 85, rate: '乙' }, // { A: 93, B: 70, rate: '丙' }, // { A: 92, B: 90, rate: '甲' } ]
在上面的这种做法中, 我们把制定策略的逻辑挪到了分配策略里了. 所以说, 如何制定策略和如何分配策略, 依情况而定.
不过回头在看一看这段代码, 是不是和平时用对象映射的做法很相似.
当然, 策略模式的用法还有很多, 最常见的是规则校验.
小结
总结一下:
- 策略模式至少包括两部分, 制定策略和分配策略.
- 策略模式的目的在于, 将策略制定和策略分配隔离开来.
- 策略制定和策略分配关系密切, 相互影响.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Javascript策略模式理解以及应用
- 产品策略模型方法论:谈谈我对产品策略模型的6点理解
- AI量化策略,我该如何理解你?
- 5分钟轻松理解二叉树的深度遍历策略
- 理解 Spark SQL 优化策略的最好方法就是自己实现一个
- 《深入理解Java虚拟机》-----第3章 垃圾收集器与内存分配策略
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
解构产品经理:互联网产品策划入门宝典
电子工业出版社 / 2018-1 / 65
《解构产品经理:互联网产品策划入门宝典》以作者丰富的职业背景及著名互联网公司的工作经验为基础,从基本概念、方法论和工具的解构入手,配合大量正面或负面的案例,完整、详细、生动地讲述了一个互联网产品经理入门所需的基础知识。同时,在此基础上,将这些知识拓展出互联网产品策划的领域,融入日常工作生活中,以求职、沟通等场景为例,引导读者将知识升华为思维方式。 《解构产品经理:互联网产品策划入门宝典》适合......一起来看看 《解构产品经理:互联网产品策划入门宝典》 这本书的介绍吧!