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设计模式之策略模式【组合委托】
前言:语言只是工具,思想才是核心 今天要总结的是 策略模式 策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式. 在实际开发中,往往在实现一个功能时,有多种解决方案可行. 常见场景: 解压: ...
随机推荐
- DbSet<T>().Where(e => true)之后再想Include怎么办?
DbSet<T>().Where(e => true)之后再想Include怎么办? 引用:https://www.cnblogs.com/godbell/p/7348411.htm ...
- 20175320 2018-2019-2 《Java程序设计》第5周学习总结
20175320 2018-2019-2 <Java程序设计>第5周学习总结 教材学习内容总结 本周学习了教材的第六章的内容.在这章中介绍了接口与实现,着重讲了接口是如何定义并实现以及如何 ...
- css学习_css精灵技术、字体图标
1.精灵技术产生的背景(减少向服务器请求的次数,减小服务器压力) 2.精灵技术的本质(小的背景图集中在一张大图上) 3.精灵技术的使用 案例1: 案例2: 注意:产品类的图片一般不是用背景,而是用im ...
- openERP笔记 自定义模块开发
##需求描述 输入和查询课程,把信息储存到课程对象里 课程包含以下信息:名称,价格,天数,开始日期,教师,学员 每个课程可以有多个学员,要记录学员的姓名.电话.电子邮件 课程可以添加教材和作业等文档附 ...
- 深度学习基础(三)NIN_Network In Network
该论文提出了一种新颖的深度网络结构,称为"Network In Network"(NIN),以增强模型对感受野内local patches的辨别能力.与传统的CNNs相比,NIN主 ...
- 快速构建一个使用axios的vue应用程序(转)
英文原文:https://www.sitepoint.com/fetching-data-third-party-api-vue-axios/ 译文:https://segmentfault.com/ ...
- vue 点击弹窗外框关闭弹框
https://blog.csdn.net/zjw0742/article/details/77822777 ready() { document.addEventListener('click', ...
- (3.1)mysql备份与恢复之mysqldump
目录: 1.单实例联系 1.1.备份单个数据库联系多种参数使用 [1]mysqldump命令备份演示 [2]查看备份文件 [3]用备份文件还原 1.2.mysqldump 各类参数释义 [1]--de ...
- python采集百度搜索结果带有特定URL的链接
#coding utf-8 import requests from bs4 import BeautifulSoup as bs import re from Queue import Queue ...
- 创建视图sql
create view 视图名称 as 查询sql语句create view test2 as select * from sc te ...