什么是策略模式?

先看代码片段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形而上的策略模式的更多相关文章

  1. 第二章 --- 关于Javascript 设计模式 之 策略模式

    这一章节里面,我们会主要的针对JavaScript中的策略模式进行理解和学习 一.定义 策略模式: 定义一系列的算法,把他们封装起来,并且是他们可以相互替换. (这样的大的定义纲领,真的不好理解,特别 ...

  2. 理解javascript中的策略模式

    理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...

  3. JavaScript设计模式(策略模式)

    策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来 ...

  4. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...

  5. JavaScript设计模式_02_策略模式

    在程序设计中,我们常常遇到这种情况,要实现某一个功能我们有很多种算法可以实现.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是所谓的策略模式. /* * pre:策略模式 * 示例:公司计算奖 ...

  6. 再起航,我的学习笔记之JavaScript设计模式20(策略模式)

    策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...

  7. JavaScript设计模式之策略模式

    所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...

  8. javascript设计模式:策略模式

    前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...

  9. JavaScript设计模式之策略模式【组合委托】

    前言:语言只是工具,思想才是核心 今天要总结的是 策略模式 策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式. 在实际开发中,往往在实现一个功能时,有多种解决方案可行. 常见场景: 解压: ...

随机推荐

  1. Centos7 安装 Ipython的方法

    环境:Centos7 最小化安装yum源设置:阿里的base源和epel源python版本:2.7.5 yum install -y python2-pip.noarchyum install -y ...

  2. CodeForces 733B Parade

    B. Parade time limit per test1 second memory limit per test256 megabytes inputstandard input outputs ...

  3. IDEA创建Spring+SpringMVC+MyBatis(SSM)极简入门(上)

    1.  创建项目 2.  添加Controller 3.  pom+ properties+swager 4.  添加Mysql+ Mybatis 5.  调用Mybatis生成Mapper 1.创建 ...

  4. python 发送带附件的邮件

    特别注意的地方:filespart.add_header("Content-Disposition","attachment",filename=file_na ...

  5. MySQL Backup mydumper

    生产环境中有一实例每天使用mysqldump备份时长达到了2个小时53分钟,接近3个小时,还不算上备份文件归档的时间,这个时间对于逻辑备份来说有点久.为了提高逻辑备份效率,打算替换为使用mydumpe ...

  6. python数据结构-如何让字典有序

    如何让字典有序 问题举例: 统计学生的成绩和名次,让其在字典中按排名顺序有序显示,具体格式如下 {'tom':(1, 99), 'lily':(2, 98), 'david':(3, 95)} 说明 ...

  7. (转载)intellj idea 如何设置类头注释和方法注释

    原文地址:http://www.cnblogs.com/wvqusrtg/p/5459327.html           intellj idea的强大之处就不多说了,相信每个用过它的人都会体会到, ...

  8. 关于UI适配的文档

    第一部分:原理 (1)根据当前屏幕尺寸与开发预设屏幕尺寸尺寸得出以下参数. 1 XRatio:当前屏幕尺寸与开发尺寸的X轴比例 2 YRtaio:当前屏幕尺寸与开发尺寸的Y轴比例 3minRatio: ...

  9. z-tree学习笔记

    做项目时,需要用到带复选框的tree.经比较后优选了ztree,功能强大,文档清晰. http://www.treejs.cn/v3/api.php 直接上代码吧. 1.下载ztree后.将里面需要用 ...

  10. COM中参数标识