《javascript设计模式与开发实践》阅读笔记(5)—— 策略模式

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

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

使用策略模式计算奖金

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

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

 1 var calculate = function( level, salary ){   //创建了一个计算函数
 2     if ( level === 'S' ){
 3         return salary * 4;
 4     }
 5     if ( level === 'A' ){
 6         return salary * 3;
 7     }
 8     if ( level === 'B' ){
 9         return salary * 2;
10     }
11 };
12 calculate( 'B', 20000 ); // 输出:40000
13 calculate( 'S', 6000 ); // 输出:24000

这段代码的缺点很多

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

 

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

 

 1 var levelS = function( salary ){
 2     return salary * 4;
 3 };
 4 var levelA = function( salary ){
 5     return salary * 3;
 6 };
 7 var levelB = function( salary ){
 8     return salary * 2;
 9 };
10 
11 var calculate = function( level, salary ){
12     if ( level === 'S' ){
13         return levelS( salary );
14     }
15     if ( level === 'A' ){
16         return levelA( salary );
17     }
18     if ( level === 'B' ){
19         return levelB( salary );
20     }
21 };
22 
23 calculate( 'A' , 10000 ); // 输出:30000

 

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

 

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

 

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

 1     var S=function( salary ){
 2             return salary * 4;
 3         };
 4 
 5     var A=function( salary ){
 6             return salary * 3;
 7         };
 8 
 9     var B=function( salary ){
10             return salary * 2;
11         }
12 
13     var calculate = function( func, salary ){   //高阶函数
14         return func( salary );
15     };
16 
17     calculate( S, 20000 );  // 输出:80000
18     calculate( A, 10000 );  // 输出:30000

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

 

 1     var Lv = {
 2         "S": function( salary ){
 3             return salary * 4;
 4         },
 5         "A": function( salary ){
 6             return salary * 3;
 7         },
 8         "B": function( salary ){
 9             return salary * 2;
10         }
11     };
12 
13     var calculate = function( level, salary ){  
14         return Lv[ level ]( salary );   //这里明确只能使用Lv对象的方法,让calulate的职能更清晰,上面calulate太过通用
15     };
16 
17     calculate( 'S', 20000 );  // 输出:80000
18     calculate( 'A', 10000 );  // 输出:30000

总结

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

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

posted @ 2016-11-21 17:57  出世Sunny  阅读(192)  评论(0编辑  收藏  举报