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设计模式之策略模式【组合委托】
前言:语言只是工具,思想才是核心 今天要总结的是 策略模式 策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式. 在实际开发中,往往在实现一个功能时,有多种解决方案可行. 常见场景: 解压: ...
随机推荐
- vim 命令补充(1)
本篇文章主要教你如何使用 Vim 分屏功能. 分屏启动Vim 使用大写的O参数来垂直分屏. vim -On file1 file2 ... 使用小写的o参数来水平分屏. vim -on file1 f ...
- 补充:ajax PHP html js 实现 三级联动(省 市 区)
html + js 在一个页面 php
- linux --- 部署前后端分离项目
vue + uwsgi +nginx 部署前后端分离项目 准备项目 1.将前端vue项目包和后端django项目包上传服务器,通过lrzsz,直接从windows拖进linux中 2.解压缩操作 前端 ...
- python-获取当前工作路径
1.sys.argv[0] import sys print sys.argv[0]#获得的是当前执行脚本的位置(若在命令行执行的该命令,则为空) 运行结果(在python脚本中执行的结果): F:/ ...
- Gym 101873G - Water Testing - [皮克定理]
题目链接:http://codeforces.com/gym/101873/problem/G 题意: 在点阵上,给出 $N$ 个点的坐标(全部都是在格点上),将它们按顺序连接可以构成一个多边形,求该 ...
- Cardinal and Ordinal Numbers
Cardinal Numbers Table of Cardinal Numbers Cardinal numbers from 1 through 1,000,000 1 one 11 eleven ...
- Python3学习之路~5.11 configparser模块
用于生成和修改常见配置文档,当前模块的名称在 python 2.x 版本中为 ConfigParser, python 3.x 版本中变更为 configparser. 来看一个好多软件的常见文档格式 ...
- Python3.6安装使用tesserocr文件时遇到问题
本机运行环境: Win 10 version 1709; Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit ...
- https://github.com/tensorflow/models/blob/master/research/slim/datasets/preprocess_imagenet_validation_data.py 改编版
#!/usr/bin/env python # Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apach ...
- cocos2d-x 贡献一个oss上传脚本
平常写前端项目和H5游戏时特别频繁的一个操作就是上传到oss上,特别浪费时间.所以用ali-oss写了一个脚本.配置属性后直接npm run oss就能上传到oss上了.再也不需要手动操作.现在是脚本 ...