JavaScript形而上的策略模式
什么是策略模式?
先看代码片段1。
// 代码片段1
var bonus = new Bonus();
bonus.setSalary(10000);
bonus.setStrategy(new performanceS());
console.log('bounsS' ,bonus.getBonus());
// => 40000
bonus.setStrategy(new performanceA());
console.log('bounsA',bonus.getBonus());
// => 30000
bonus是一个对象,而对象自带上下文。
这个对象在运行的不同阶段,通过setStrategy设置了不同的参数,导致同样的bonus.getBonus()输出结果不同。
所以策略模式是指,定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
下面的代码片段2是代码片段1的定义。
// 代码片段2
var performanceS = function () { };
performanceS.prototype.calculate = function (salary) {
return salary * 4;
};
var performanceA = function () { };
performanceA.prototype.calculate = function (salary) {
return salary * 3;
};
var performanceB = function () { };
performanceB.prototype.calculate = function (salary) {
return salary * 2;
};
var Bonus = function () {
this.salary = null;
this.strategy = null;
};
Bonus.prototype.setSalary = function (salary) {
this.salary = salary;
};
Bonus.prototype.setStrategy = function (strategy) {
this.strategy = strategy;
};
Bonus.prototype.getBonus = function () {
return this.strategy.calculate(this.salary);
};
改进的策略模式
同样的bonus.getBonus(),却输出结果不同。
当业务变得复杂,这会导致代码难以预测。
我们稍微改进一下,让对象初始化时接收一个策略对象,并且设置策略属性不可修改。
// 代码片段3
var bonusFactory = function(strategy){
this.salary = null;
Object.defineProperty(this, 'strategy',{
value: strategy,
writable: false,
configurable:false,
})
};
bonusFactory.prototype.setSalary = function (salary) {
this.salary = salary;
};
bonusFactory.prototype.getBonus = function () {
return this.strategy.calculate(this.salary);
};
var bonusS = new bonusFactory(new performanceS());
bonusS.setSalary(10000);
bonusS.strategy = 11;
console.log('bonusS', bonusS.getBonus());
var bonusA = new bonusFactory(new performanceA());
bonusA.setSalary(10000);
console.log('bonusA', bonusA.getBonus());
策略模式的函数式写法
这里使用了名为ramda的函数式工具库。
var R = require('ramda');
var salaryS = function(salary) {
return salary * 4;
};
var salaryA = function(salary) {
return salary * 3;
};
var salaryB = function(salary) {
return salary * 2;
};
var getBonus = function(salary, strategy){
return strategy(salary);
};
var getBonusFacotry = R.curry(getBonus);
var getBonusS = getBonusFacotry(R.__, salaryS);
var getBonusA = getBonusFacotry(R.__, salaryA);
var getBonusB = getBonusFacotry(R.__, salaryB);
var getBouns1000 = getBonusFacotry(1000, R.__);
console.log('封装奖金计算方式的策略');
console.log(getBonusS(1000));
console.log(getBonusA(1000));
console.log(getBonusB(1000));
console.log('封装奖金数目的策略');
console.log(getBouns1000(salaryS));
console.log(getBouns1000(salaryA));
console.log(getBouns1000(salaryB));
可以看到函数式写法更加灵活和简洁。
JavaScript形而上的策略模式的更多相关文章
- 第二章 --- 关于Javascript 设计模式 之 策略模式
这一章节里面,我们会主要的针对JavaScript中的策略模式进行理解和学习 一.定义 策略模式: 定义一系列的算法,把他们封装起来,并且是他们可以相互替换. (这样的大的定义纲领,真的不好理解,特别 ...
- 理解javascript中的策略模式
理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...
- JavaScript设计模式(策略模式)
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来 ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- JavaScript设计模式_02_策略模式
在程序设计中,我们常常遇到这种情况,要实现某一个功能我们有很多种算法可以实现.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是所谓的策略模式. /* * pre:策略模式 * 示例:公司计算奖 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- javascript设计模式:策略模式
前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...
- JavaScript设计模式之策略模式【组合委托】
前言:语言只是工具,思想才是核心 今天要总结的是 策略模式 策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式. 在实际开发中,往往在实现一个功能时,有多种解决方案可行. 常见场景: 解压: ...
随机推荐
- ajax获取后台数据渲染(整片文章不分段落)解决方案,要使用htmL方式输出
方案一:使用 HTML pre tag<div class="content"><pre> {{ text_data }}</pre></ ...
- sj 网页前端与后台数据交互的3种方式
1.ajax 网页访问 2.form 表单 用户名<input class="yonghu" type="text" id="user&quo ...
- F#周报2019年第2期
新闻 Rider上的拼写助手,对未使用引用的代码分析及更多F#相关特性的更新 .NET开源革命开始 ML.NET 0.9发布记录 测试驱动的集成开发环境 Giraffe在GitHub上超过了1000个 ...
- 安装ipa文件
https://www.jianshu.com/p/419a35f9533a 1.通过iTunes直接拖动到左侧的侧边栏(未尝试) 2.通过Xcode点击进入Devices管理,添加ipa文件进行安装 ...
- 单片机小白应该如何学习stm32的一些实践心得!
嵌入式搬砖道路上的大三狗一枚,撑死算个初学者吧.才学有限,下面仅仅是本人对STM32学习的一点心得与建议,希望对题主有帮助吧. 心得:本人当初学习STM32的时候有一些跟风的因素,自以为学的芯片越多就 ...
- Linux下/usr/bin与/usr/local/bin/区别总结
Linux下/usr/bin与/usr/local/bin/区别总结 2017年10月13日 12:30:17 2puT 阅读数:15930 版权声明:本文为博主原创文章! github地址:h ...
- vue-property-decorator 提供 OO 的风格 Vue Component 方便类型声明
@Prop 父子组件之间传值 Install: npm install --save vue-property-decorator Child: <template> <div&g ...
- WebSocket 学习教程(二):Spring websocket实现消息推送
=============================================== 环境介绍: Jdk 1.7 (1.6不支持) Tomcat7.0.52 (支持Websocket协议) ...
- python基础(8)-装饰器函数&进阶
从小例子进入装饰器 统计一个函数执行耗时 原始版本 import time # time模块有提供时间相关函数 def do_something(): print("do_something ...
- Cartographer源码阅读(8):imu_tracker
IMU的输入为imu_linear_acceleration 和 imu_angular_velocity 线加速和角速度.最终作为属性输出的是方位四元数. Eigen::Quaterniond ...