博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript设计模式 策略模式
阅读量:6831 次
发布时间:2019-06-26

本文共 3756 字,大约阅读时间需要 12 分钟。

在现实中,我们到达一个地方,通常可以选择不同的方式,例如自行车,火车,汽车,飞机等。

在程序设计中,通常也会有这样的情况,实现一个功能有多个方案可以选择,比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法。

而这种情况,在设计模式中,称为策略模式。

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

例子:

很多公司的年终奖是根据员工的工资基数和年底绩效情况来方法的。如S级绩效为4倍工资,A级有3倍工资,B级有两倍工资。

在不使用策略模式的情况下,通常这样设计代码:

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("A",2500); // 输出7500

可以发现,这段代码非常简单,但也有很大的问题。

1.calculateBonus函数比较庞大,包含了很多if-else语句,这些语句需要覆盖所有的逻辑分支。

2.缺乏弹性,如果增加了绩效等级C,需要深入函数内部修改。

3.算法复用性差,重用只能通过复制粘贴。

 

使用策略模式重构代码。

策略模式的程序至少由两部分组成,第一部分是策略类,策略类封装了具体的算法,并负责具体的计算过程。第二部分是环境类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.starategy = 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);    };    //测试    var bonus = new Bonus();    bonus.setSalary(2000);    bonus.setStrategy(new performanceS);      console.log(bonus.getBonus())         // 输出8000    bonus.setSalary(3000);    bonus.setStrategy(new performanceB);      console.log(bonus.getBonus())         //输出6000

在上面的例子中,Bonus充当了环境类,将客户的请求委托给策略类的某一个。

 

在Js中,实际可以有更方便的做法,Js的函数也是对象,也就是函数也可以作为参数调用。

//策略类    var performanceS = function(salary){        return salary*4;    };    var performanceA = function(salary){        return salary*3;    };    var performanceB = function(salary){        return salary*2;    };    //环境类    var bonus = function(fn,salary){        return fn(salary);    };    //测试    console.log(bonus(performanceS,1000));  //输出4000    console.log(bonus(performanceB,3000));  //输出6000

 

 

策略模式的优缺点:

优点:

       1.利用组合、委托、多态等技术和思想,避免多重条件选择语句。

       2.易于切换、理解、扩展。

       3.可以复用。

缺点:

       1.拥有许多策略类或者策略对象,实际上比把它们负责的逻辑堆砌在Context中要好。

       2.用户比须了解所有的策略类,才能选择一个最合适的策略类。

 

最后,通过策略模式实现一个表单验证:

 

define(function(){    var input_judge = {             noNull:function(value,errorMsg){                 if(!value)                     return errorMsg;             },             minLen:function(value,length,errorMsg){                 if(value.length
length) return errorMsg; }, NumAndLetter:function(value,errorMsg){ var regNum = /[0-9]/; var regLet = /[a-zA-Z]/; var regAll = /^[0-9a-zA-Z]+$/ if(!regNum.test(value) || !regLet.test(value) || !regAll.test(value)) return errorMsg; }, Email:function(value,errorMsg){ var reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; if(!reg.test(value)) return errorMsg; } }; //添加规则 function add(domInput,rule,errorMsg){ domInput = $(domInput)[0]; domInput.Check = domInput.Check ? domInput.Check : []; domInput.errorMsg = ""; for(var i=0,length = rule.length;i

 

转载于:https://www.cnblogs.com/Darlietoothpaste/p/6675575.html

你可能感兴趣的文章
Jquery实现鼠标拖拽效果
查看>>
标准差(standard deviation)和标准误差(standard error)你能解释清楚吗?
查看>>
[WPF]有滑动效果的进度条
查看>>
妙趣横生的算法--顺序表
查看>>
Xcode 5.0.2 下载地址
查看>>
Z.Studio高级成衣定制(双井店)价格,地址(图)-北京-大众点评网
查看>>
定时器
查看>>
【LeetCode】120. Triangle (3 solutions)
查看>>
boost::interprocess(1)
查看>>
Noi2011 : 智能车比赛
查看>>
设置tomcat 编译文件位置【转】
查看>>
NOI2010 : 超级钢琴
查看>>
sine曲线向前运动
查看>>
ios的@property属性和@synthesize属性(转)
查看>>
四种常见的 POST 提交数据方式
查看>>
编写一个C语言函数,要求输入一个url,输出该url是首页、目录页或者其他url
查看>>
ubuntu 14.04 chromium,firefox 怎样正确安装Adobe flash player
查看>>
Linux makefile 教程 很具体,且易懂
查看>>
linux用dd测试磁盘速度
查看>>
八大排序算法总结
查看>>