zoukankan      html  css  js  c++  java
  • 《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中,使得它们易于切换,易于理解,易于扩展。

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

  • 相关阅读:
    HTTPS证书申请相关笔记
    180508
    如何通过 AAR 形式集成 leakcanary-android 服务
    Mysql命令大全
    Python3.x和Python2.x的区别 (转)
    Python学习笔记(二)
    for循环处理列表的显示
    Python学习笔记
    python环境搭建
    Linux下JDK环境的配置
  • 原文地址:https://www.cnblogs.com/grey-zhou/p/6086371.html
Copyright © 2011-2022 走看看