策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

我的理解就是把各种方法封装成函数,同时存在一个可以调用这些方法的公共函数。这样做的好处是可以消化掉内部的分支判断,使代码效率更高。

使用策略模式计算奖金

现在要实现这样一个东西,年终奖是根据员工的工资基数和年底绩效情况来发放的。例如,绩效为S的人年终奖有4倍工资,绩效为A的人年终奖有3倍工资,而绩效为B的人年终奖是2倍工资。假设财务部要求我们提供一段代码,来方便他们计算员工的年终奖。

思路一:创建一个函数,接收两个参数,一个是绩效,一个是工资底数,然后返回年终奖

 var calculate = function( level, salary ){   //创建了一个计算函数
if ( level === 'S' ){
return salary * 4;
}
if ( level === 'A' ){
return salary * 3;
}
if ( level === 'B' ){
return salary * 2;
}
};
calculate( 'B', 20000 ); // 输出:40000
calculate( 'S', 6000 ); // 输出:24000

这段代码的缺点很多

(1)calculate函数比较庞大,包含了很多if语句,这些语句需要覆盖所有的逻辑分支
(2)函数缺乏弹性,如果增加了一种新的绩效等级C,或者想把绩效S的奖金系数改为5,那我们必须深入calculate函数的内部实现,这是违反开放-封闭原则的。

思路二:用组合函数完成,一个函数用来计算相应奖金,另一个函数用来判断调用哪个计算函数

 var levelS = function( salary ){
return salary * 4;
};
var levelA = function( salary ){
return salary * 3;
};
var levelB = function( salary ){
return salary * 2;
}; var calculate = function( level, salary ){
if ( level === 'S' ){
return levelS( salary );
}
if ( level === 'A' ){
return levelA( salary );
}
if ( level === 'B' ){
return levelB( salary );
}
}; calculate( 'A' , 10000 ); // 输出:30000

这段代码比上面的好一些,但是还是没解决关键问题,calculate函数有可能变得越来越大,而且函数依旧缺乏弹性。

思路三:策略模式,将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来。

策略模式就是分成策略函数和调用函数,调用函数不应该包含分支判断,调用任何策略函数的方式应该是一致的:

     var S=function( salary ){
return salary * 4;
}; var A=function( salary ){
return salary * 3;
}; var B=function( salary ){
return salary * 2;
} var calculate = function( func, salary ){ //高阶函数
return func( salary );
}; calculate( S, 20000 ); // 输出:80000
calculate( A, 10000 ); // 输出:30000

或者使用对象,让策略彼此间可以产生联系:

     var Lv = {
"S": function( salary ){
return salary * 4;
},
"A": function( salary ){
return salary * 3;
},
"B": function( salary ){
return salary * 2;
}
}; var calculate = function( level, salary ){
return Lv[ level ]( salary ); //这里明确只能使用Lv对象的方法,让calulate的职能更清晰,上面calulate太过通用
}; calculate( 'S', 20000 ); // 输出:80000
calculate( 'A', 10000 ); // 输出:30000

总结

策略模式的优点
  策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。
  策略模式提供了对开放—封闭原则的完美支持,将算法封装在独立的strategy中,使得它们易于切换,易于理解,易于扩展。

总结一下就是将策略函数封装,调用函数的实质就是调用这些策略函数

javascript设计模式与开发实践阅读笔记(5)——策略模式的更多相关文章

  1. javascript设计模式与开发实践阅读笔记(4)——单例模式

    定义 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 具体来说,就是保证有些对象有且只有一个,比如线程池.全局缓存.浏览器中的window 对象等.在js中单例模式用途很广,比如登录 ...

  2. javascript设计模式与开发实践阅读笔记(8)——观察者模式

    发布-订阅模式,也叫观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 在JavaScript开发中,我们一般用事件模型来替代传统的观察者模式. ...

  3. javascript设计模式与开发实践阅读笔记(7)——迭代器模式

    迭代器模式:指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺 ...

  4. javascript设计模式与开发实践阅读笔记(6)——代理模式

    代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对 ...

  5. javascript设计模式与开发实践阅读笔记(9)——命令模式

    命令模式:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么,此时希望用一种松耦合的方式来设计软件,使得请求发送者和请求接收者能够消除彼此之间的耦合关系. 说法很复 ...

  6. javascript设计模式与开发实践阅读笔记(11)—— 模板方法模式

    模板方法模式: 由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序.子类通过继承这个抽象类,也继 ...

  7. JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)

    说来惭愧,4个多月未更新了.4月份以后就开始忙起来了,论文.毕设.毕业旅行等七七八八的事情占据了很多时间,毕业之后开始忙碌的工作,这期间一直想写博客,但是一直没能静下心写.这段时间在看<Java ...

  8. 《JavaScript设计模式与开发实践》笔记第八章 发布-订阅模式

    第八章 发布-订阅模式 发布-订阅模式描述 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布-订阅模式可以广泛应用于 ...

  9. JavaScript设计模式与开发实践——读书笔记1.高阶函数(下)

    上部分主要介绍高阶函数的常见形式,本部分将着重介绍高阶函数的高级应用. 1.currying currying指的是函数柯里化,又称部分求值.一个currying的函数会先接受一些参数,但不立即求值, ...

随机推荐

  1. Parameter Passing / Request Parameters in JSF 2.0 (转)

    This Blog is a compilation of various methods of passing Request Parameters in JSF (2.0 +) (1)  f:vi ...

  2. TTL 生存时间介绍 (转)

    TTL: (Time To Live)生存时间,是IP协议包中的一个值,它告诉网络路由器包在网络中的时间是否太长而应被丢弃.有很多原因使包在一定时间内不能被传递到目的地.例如,不正确的路由表可能导致包 ...

  3. [转]彻底征服Word 2007标题多级列表

    [转]彻底征服Word 2007标题多级列表 用Word编写文档的人都知道,一篇长文档一般是需要分章节来划分段落的.在Word中也有对应的工具来完成这项任务,这就是多级列表.然而绝大多数使用Micro ...

  4. 多进程模块multiprocessing的使用

    该模块提供如下功能: 建立并管理运行指定函数的子进程 基本接口: 1 Process(group, target, name, args[, kwargs]): 初始化子进程对象 2 p.daemon ...

  5. cocos2d-x项目实现android视频播放参考链接

    http://blog.csdn.net/xiaominghimi/article/details/6870259 http://blog.csdn.net/kaitiren/article/deta ...

  6. .NET Framework 基础知识总结

    C#: 1. public:同一个程序集的任何代码或引用该程序集的其他程序集都可以访问该类型或成员 internal:同一个程序集的任何代码都可以访问该类型或成员 private :只有在结构或类中的 ...

  7. 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)

    好长时间没有用过Spring了. 突然拿起书.我都发现自己对AOP都不熟悉了. 其实AOP的意思就是面向切面编程. OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决解决问 ...

  8. 解剖SQLSERVER 第十五篇 SQLSERVER存储过程的源文本存放在哪里?(译)

    解剖SQLSERVER 第十五篇  SQLSERVER存储过程的源文本存放在哪里?(译) http://improve.dk/where-does-sql-server-store-the-sourc ...

  9. 强大好用的"文本"编辑器

    1 editplugs 说明:EditPlus是一款由韩国 Sangil Kim (ES-Computing)出品的小巧但是功能强大的可处理文本.HTML和程序语言的Windows编辑器,你甚至可以通 ...

  10. LIstView 滚动 异步 加载更多 mono for android ScrollStateChanged ScrollState.Idle; Fling;TouchScroll

    今天项目需要实现一下列表的分页加载 找到了Listview的ScrollStateChanged方法. 和大家分享一下 //先找到Listview ListView order = FindViewB ...