• javascript策略模式


         策略模式的定义是:定义一系列的算法,把它们都封装起来,并使它们可以互相替换。
         实例一:使用策略模式计算奖金
         很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的。例如,绩效为S的人年终奖有4倍工资,绩效为A的人年终奖为3倍工资,绩效为B的人年终奖为2倍工资。代码的最初实现为:
        var calculateBonus = function(performanceLevel, salary){
             if(performanceLevel == 'S'){
                  return salary * 4;
             }
             if(performanceLevel == 'A'){
                  return salary * 3;
             }
             if(performanceLevel == 'B'){
                  return salary * 2;
             }
         }

         calculateBonus('B',2000); // 输出:4000
         calculateBonus('s',5000); // 输出:20000

         上面的代码非常简单,但有很明显的缺点。
         1.calculateBonus函数也许会非常庞大,那会包含很多if-else语句
         2.calculateBonus函数缺乏弹性,如果增加一种新的绩效,或者想修改绩效,那就必须得深入calculateBonus函数内部实现,这是违反开放-封闭原则的。
         3.算法的复用性差,如果要在程序的其它地方重用这些代码,就只能复制和粘贴。

         所以这段代码需要重构。

         使用组合函数重构代码:
         var performanceS = function(salary){
              return salary * 4;
         }
         var performanceA = function(salary){
              return salary * 3;
         }
         var performanceB = function(salary){
              return salary * 2;
         }

         var calculateBonus = function(performanceLevel, salary){
              if(performanceLevel == 'S'){
                   return performanceS(salary);
              }
              if(performanceLevel == 'A'){
                   return performanceA(salary);
              }
              if(performanceLevel == 'B'){
                   return performanceB(salary);
              }
          }

          calculateBonus('s',5000); // 输出:20000


          使用策略模式重构代码:
          一个基于策略模式的程序至少由两部分组成。第一部分是一组策略类,封装了具体的算法,负责具体的计算过程。第二部分是环境类Context,Context接受客户的请求,随后委托给某一个策略类(要做到这点,说明Context要维持对某个策略对象的引用)。下面是模仿传统面向对象语言中的实现:
          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(stratege){
                this.strategy = strategy; //设置绩效等级
          }
          Bonus.prototype.getBonus = function(){ //取得奖金数额
                return this.strategy.calculate(this.salary);
          }

          var bonus = new Bonus();
          bonus.setSalary(10000);
          bonus.setStrategy( new performanceS() );

          console.log(bonus.getBonus()); // 输出 40000

          javascript版本的策略模式:
          var strategies = {
               "S":function(salary){
                       return salary * 4;
                     },
               "A":function(salary){
                       return salary * 3;
                     },
               "B":function(salary){
                       return salary * 2;
                     }
           };

           var calculateBonus = function(level, salary){
                return strategies[ level ]( salary );
           };

           console.log( calculateBonus( 'S' , 15000 ) ); // 输出 60000

          策略模式的优缺点:
          1.策略模式利用组合、委托和多态等技术思想,可以有效地避免多重条件选择语句
          2.策略模式提供了对开放-封闭原则的支持,将算法封装在独立的对象中,这样易于切换、易于理解、易于理解
          3.在策略模式中,可以将算法复用在程序的其它地方,避免复制粘贴代码
          4.在粗略模式中利用组合和委托来让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案

          缺点:
          首先,使用策略模式会在程序中增加许多策略类或者策略对象(但实际上这比把它们负责的逻辑放在Context中要好)。
          其次,要使用策略模式,就得了解策略模式中所有的选项,此时就必须要向客户暴露策略类的所有实现,这就违反了最少知识原则

  • 相关阅读:
    java谜题
    Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' 的解决办
    考虑用静态工厂代替构造器
    Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' 的解决办
    100 个高质量的 XHTML/CSS 模板(上)
    登陆时的安全性
    Flex 开发架构(五): Mate-基于标签的框架
    NIO的基本概念及简单示例
    Flex与jsp的联系
    福布斯:Sun的六大失误
  • 原文地址:https://www.cnblogs.com/xbj-2016/p/5807169.html
Copyright © 2020-2023  润新知