策略模式

阅读 / 问答 / 标签

策略模式实际上应用了什么设计原则

1.Petshop中策略模式的应用 至于在程序中的应用,我也是个新手,不知道何时需要这种模式,可以参考下petshop中的策略模式,理解下在真实项目中如何使用。我对petshop中策略模式的理解就是里面处理订单时可能有同步和异步插入数据两种方式,具体用那种方式直接在配置文件中修改即可。看文字不如看图片,自己画了画UML图,不会用工具但是意思差不多。 这是IBLLStrategy类库中的接口IBLLStrage,为了同步异步插入订单的实现,如果有新的订单插入方式,可以继承此接口这两个类是处理同步异步的订单类。继承于IBLLStrage,分别实现自己的插入方法。在BLL层中的order类中private static readonly PetShop.IBLLStrategy.IOrderStrategy orderInsertStrategy = LoadInsertStrategy();LoadInsertStrategy方法决定了实例化的是同步传送订单还是异步传送订单。在BLL逻辑层中,Order订单中会改变的是insert方法,所以根据设计原则,把需要改变的独立出来。 2.控制台小应用程序 实例描述,模拟鸭子应用,由于后期需要可能有N种鸭子,鸭子可不可以飞,怎样飞,鸭子可不可以叫,怎么叫,如果仅仅写两个接口Ifly和Iquack,子类要么继承,要么不继承,对飞的行为无法控制,因为飞的动作和叫的方式千变万化。设计原则 1.找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混合在一起(此例子中鸭子的行为属于变化) 2.针对接口编程,而不是针对实现编程针对接口编程是真正的意思是针对超类型编程,利用多态,程序可以针对超类型编程,声明一个类时通常是一个超类或者是一个接口,这也意味着声明类时,不用理会以后执行的真正对象,举例Animal是一个抽象类,有两个子类Dog和Cat继承Animal针对实现的编程是: Cat c = new Cat(); c.meow(); //猫叫的方式 Dog d = new Dog(); d.bark(); //狗叫的方式针对接口的编程是: Animal a = new Dog(); a.makeSound(); //makeSound中会调用bark(); Animal a = new Cat(); a.makeSound(); //makeSound中会调用meow(); 3.多用组合,少用继承根据读headfirst策略模式做的c#的例子。 策略模式:定义了算法族,分别封装起来,让他们之间可以相互替换,次模式让算法的变化独立于使用算法的客户。

设计模式的策略模式怎样在前端中使用

上边这句话,从字面来看很简单。但是如何在开发过程中去应用,仅凭一个定义依然是一头雾水。以笔者曾经做过的商户进销存系统为例:某超市准备举行促销活动,市场人员经过调查分析制定了一些促销策略:购物满100减10购物满200减30购物满300减50。。收银软件的界面是这样的(简单示意):我们应该如何计算实际消费金额?最初的实现是这样的://方便起见,我们把各个促销策略定义为枚举值:0,1,2...var getActualTotal = function(onSaleType,originTotal){ if(onSaleType===0){ return originTotal-Math.floor(originTotal/100)*10 } if(onSaleType===1){ return originTotal-Math.floor(originTotal/200)*30 } if(onSaleType===0){ return originTotal-Math.floor(originTotal/300)*50 }}getActualTotal(1,2680); //2208上面这段代码很简单,而且缺点也很明显。随着我的满减策略逐渐增多,getActualTotal函数会越变越大,而且充满了if判断,稍一疏忽就容易弄错。OK,有人说我很懒,虽然这样不够优雅但并不影响我的使用,毕竟满减策略再多也多不到哪去。我只能说,需求永远不是程序员定的。这时,市场人员说我们新版程序添加了会员功能,我们需要支持以下的促销策略:会员促销策略:会员充300返60,且首单打9折会员充500返100,且首单打8折会员充1000返300,且首单打7折...这个时候,如果你还在原先的getActualTotal函数中继续添加if判断,我想如果你的领导review你这段代码,可能会怀疑自己当初怎么把你招进来。OK,我们终于下定决心要重构促销策略的代码,我们可以这么做:var vipPolicy_0=function(originTotal){ return originTotal-Math.floor(originTotal/100)*10}var vipPolicy_1=function(originTotal){ return originTotal-Math.floor(originTotal/200)*30}...//会员充1000返300var vipPolicy_10=function(account,originTotal){ if(account===0){ account+=1300; return originTotal*0.9 }else{ account+=1300; return originTotal; } return originTotal-Math.floor(originTotal/200)*30}...var vipPolicy_n=function(){ ...}var getActualTotal=function(onSaleType,originTotal,account){ switch(onSaleType){ case 0: return vipPolicy_0(originTotal); case 1: return vipPolicy_0(originTotal); ... case n: return ... default: return originTotal; }}好了,现在我们每种策略都有自己独立的空间了,看起来井井有条。但是还有两个问题没有解决:随着促销策略的增加,getActualTotal的代码量依然会越来越大系统缺乏弹性,如果需要增加一种策略,那么除了添加一个策略函数,还需要修改switch...case..语句让我们再来回顾一下策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换在我们的例子中,每种促销策略的实现方式是不一样的,但我们最终的目的都是为了求得实际金额。策略模式可以把我们对促销策略的算法一个个封装起来,并且使它们可互相替换而不影响我们对实际金额的求值,这正好是我们所需要的。下面我们用策略模式来重构上面的代码:var policies={ "Type_0":function(originTotal){ return originTotal-Math.floor(originTotal/100)*10 }, "Type_1":function(originTotal){ return originTotal-Math.floor(originTotal/200)*30 }, ... "Type_n":function(originTotal){ ... }}var getActualTotal=function(onSaleType,originTotal,account){ return policies["Type_"+onSaleType](originTotal,account)}//执行getActualTotal(0,2680.00);//2208分析上面的代码我们发现,不管促销策略如何增加,getActualTotal函数完全不需要再变化了。我们要做的,就是增加新策略的函数而已。通过策略模式的代码,我们消除了让人反胃的大片条件分支语句,getActualTotal本身并没有计算能力,而是将计算全权委托给了策略函数。由此我们可以总结出策略模式实现的要点:将变化的算法封装成独立的策略函数,并负责具体的计算委托函数,该函数接受客户请求,并将请求委托给某一个具体的策略函数用一张UML图表示如下:怎么样?现在看到上面这张图是不是有了了然于胸的感觉?那就赶紧去试一试策略模式吧!参考书籍:《设计模式:可复用面向对象软件的基础》《大话设计模式》《Javascript设计模式与开发实践》做前端开发已经好几年了,对设计模式一直没有深入学习总结过。随着架构相关的工作越来越多,越来越能感觉到设计模式成为了我前进道路上的一个阻碍。所以从今天开始深入学习和总结经典的设计模式以及面向对象的几大原则。今天第一天,首先来讲策略模式。什么是策略模式?GoF四兄弟的经典《设计模式》中,对策略模式的定义如下:定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换。上边这句话,从字面来看很简单。但是如何在开发过程中去应用,仅凭一个定义依然是一头雾水。以笔者曾经做过的商户进销存系统为例:某超市准备举行促销活动,市场人员经过调查分析制定了一些促销策略:购物满100减10购物满200减30购物满300减50。。收银软件的界面是这样的(简单示意):我们应该如何计算实际消费金额?最初的实现是这样的://方便起见,我们把各个促销策略定义为枚举值:0,1,2...var getActualTotal = function(onSaleType,originTotal){ if(onSaleType===0){ return originTotal-Math.floor(originTotal/100)*10 } if(onSaleType===1){ return originTotal-Math.floor(originTotal/200)*30 } if(onSaleType===0){ return originTotal-Math.floor(originTotal/300)*50 }}getActualTotal(1,2680); //2208上面这段代码很简单,而且缺点也很明显。随着我的满减策略逐渐增多,getActualTotal函数会越变越大,而且充满了if判断,稍一疏忽就容易弄错。OK,有人说我很懒,虽然这样不够优雅但并不影响我的使用,毕竟满减策略再多也多不到哪去。我只能说,需求永远不是程序员定的。这时,市场人员说我们新版程序添加了会员功能,我们需要支持以下的促销策略:会员促销策略:会员充300返60,且首单打9折会员充500返100,且首单打8折会员充1000返300,且首单打7折...这个时候,如果你还在原先的getActualTotal函数中继续添加if判断,我想如果你的领导review你这段代码,可能会怀疑自己当初怎么把你招进来。OK,我们终于下定决心要重构促销策略的代码,我们可以这么做:var vipPolicy_0=function(originTotal){ return originTotal-Math.floor(originTotal/100)*10}var vipPolicy_1=function(originTotal){ return originTotal-Math.floor(originTotal/200)*30}...//会员充1000返300var vipPolicy_10=function(account,originTotal){ if(account===0){ account+=1300; return originTotal*0.9 }else{ account+=1300; return originTotal; } return originTotal-Math.floor(originTotal/200)*30}...var vipPolicy_n=function(){ ...}var getActualTotal=function(onSaleType,originTotal,account){ switch(onSaleType){ case 0: return vipPolicy_0(originTotal); case 1: return vipPolicy_0(originTotal); ... case n: return ... default: return originTotal; }}好了,现在我们每种策略都有自己独立的空间了,看起来井井有条。但是还有两个问题没有解决:随着促销策略的增加,getActualTotal的代码量依然会越来越大系统缺乏弹性,如果需要增加一种策略,那么除了添加一个策略函数,还需要修改switch...case..语句让我们再来回顾一下策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换在我们的例子中,每种促销策略的实现方式是不一样的,但我们最终的目的都是为了求得实际金额。策略模式可以把我们对促销策略的算法一个个封装起来,并且使它们可互相替换而不影响我们对实际金额的求值,这正好是我们所需要的。下面我们用策略模式来重构上面的代码:var policies={ "Type_0":function(originTotal){ return originTotal-Math.floor(originTotal/100)*10 }, "Type_1":function(originTotal){ return originTotal-Math.floor(originTotal/200)*30 }, ... "Type_n":function(originTotal){ ... }}var getActualTotal=function(onSaleType,originTotal,account){ return policies["Type_"+onSaleType](originTotal,account)}//执行getActualTotal(0,2680.00);//2208分析上面的代码我们发现,不管促销策略如何增加,getActualTotal函数完全不需要再变化了。我们要做的,就是增加新策略的函数而已。通过策略模式的代码,我们消除了让人反胃的大片条件分支语句,getActualTotal本身并没有计算能力,而是将计算全权委托给了策略函数。由此我们可以总结出策略模式实现的要点:将变化的算法封装成独立的策略函数,并负责具体的计算委托函数,该函数接受客户请求,并将请求委托给某一个具体的策略函数用一张UML图表示如下:怎么样?现在看到上面这张图是不是有了了然于胸的感觉?那就赶紧去试一试策略模式吧!相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!推荐阅读:怎样使用JS+H5实现微信摇一摇如何对微信小程序进行开发