1、第三章第三章 策略模式策略模式韩韩 格格2011年年3月月提纲提纲3.1 问题描述问题描述3.2 典型案例典型案例 3.3 策略模式策略模式3.4 效果与适应性效果与适应性3.1 问题描述问题描述 w 问题问题-在处理客户相同的业务时,可能有不同的逻辑处理算在处理客户相同的业务时,可能有不同的逻辑处理算法。客户需要多种不同的算法实现。法。客户需要多种不同的算法实现。-客户希望在运行时根据上下文选择其中一个算法。使客户希望在运行时根据上下文选择其中一个算法。使用算法的类变得复杂而难于维护,尤其当需要支持多用算法的类变得复杂而难于维护,尤其当需要支持多种算法且每种算法都很复杂时问题会更加严重;种算
2、法且每种算法都很复杂时问题会更加严重;-不同时候需要不同的算法,支持并不使用的算法可能不同时候需要不同的算法,支持并不使用的算法可能带来性能的负担;带来性能的负担;-算法的实现和使用算法的对象紧紧耦合在一起,使新算法的实现和使用算法的对象紧紧耦合在一起,使新增算法或修改算法变得十分困难,系统应对变化的能增算法或修改算法变得十分困难,系统应对变化的能力很差。力很差。3.1 问题描述问题描述w方法方法-依据面向对象的思想,我们所能想到的办法就依据面向对象的思想,我们所能想到的办法就是将每种算法的实现都剥离出来构成一个个独是将每种算法的实现都剥离出来构成一个个独立的算法对象,再从这些算法对象中抽象出
3、公立的算法对象,再从这些算法对象中抽象出公共的算法接口,最后将算法接口组合到使用算共的算法接口,最后将算法接口组合到使用算法的类中。上述思路就引入了一个新的设计模法的类中。上述思路就引入了一个新的设计模式策略模式。式策略模式。3.2 典型案例典型案例w 超市打折收银软件超市打折收银软件为提高超市收益,超市开展促销活动。除了正常收费方式为提高超市收益,超市开展促销活动。除了正常收费方式外,添加对某些产品打折收费和满额返现收费方式。例如:外,添加对某些产品打折收费和满额返现收费方式。例如:商品打商品打8折、打折、打7折、满折、满300元消费返回元消费返回100元、满元、满500返返200。实现能够
4、计算总收费额度的功能。实现能够计算总收费额度的功能。如何添加和修改如何添加和修改各式各样的多种各式各样的多种收费方式收费方式?3.2 典型案例典型案例3.2 典型案例典型案例w 收银软件设计类图收银软件设计类图CashContext+GetResult():doubleCashNormal+acceptCash():doubleCashSuper+acceptCash():doubleCashRebate+acceptCash():doubleCashReturn+acceptCash()3.2 典型案例典型案例abstract class CashSuper /收取现金的父类收取现金的父类
5、public abstract double AcceptCash(double cash);class CashRebate:CashSuper /按一定打折率收取现金类按一定打折率收取现金类 private double discount=1.0;public CashRebate(double _discount)discount=_discount;public override double AcceptCash(double cash)return cash*discount;w 部分核心源码部分核心源码3.2 典型案例典型案例 public virtual GroupBox Cr
6、eateGroupBox(String title,Control control)GroupBox gb=new GroupBox();gb.Text=title;gb.Dock=DockStyle.Fill;gb.Controls.Add(control);control.Dock=DockStyle.Fill;return gb;public virtual Panel CreatePanel()Panel pl=new Panel();pl.BackColor=Color.White;pl.Paint+=new PaintEventHandler(pl_Paint);return pl
7、;protected void pl_Paint(object sender,PaintEventArgs pea)int nPoint=101;double w=(Panel)sender).Width-1;double h=(Panel)sender).Height-1;Point points=new PointnPoint;for(int i=0;i nPoint;i+)double t=(double)i)/(nPoint-1);pointsi.X=(int)(t*w);pointsi.Y=(int)(4*h*(t-.5)*(t-.5);Pen p=new Pen(Color.Bla
8、ck);Graphics g=pea.Graphics;g.DrawLines(p,points);3.3 策略模式策略模式w 策略模式(策略模式(Strategy)-它定义了算法家族,分别对其封装起来,通过它定义了算法家族,分别对其封装起来,通过基类让它们之间可以相互替换,而算法的变化基类让它们之间可以相互替换,而算法的变化不会影响到使用算法的客户。不会影响到使用算法的客户。3.3 策略模式策略模式Strategy+AlgorithmInterface()ConcreteStrategyA+AlgorithmInterface()Context-Strategy+ContextInterfa
9、ce()Context类是配置上下文,其中包含一个Strategy对象作为属性,并对其进行维护Strategy策略类,定义了所有受支持算法的接口继承于Strategy的具体策略类,封装了具体的算法或行为ConcreteStrategyB+AlgorithmInterface()ConcreteStrategyC+AlgorithmInterface()策略模式类结构图3.4 效果与适应性效果与适应性w 优点优点-策略模式定义一系列算法,从概念上来看,所有这些算策略模式定义一系列算法,从概念上来看,所有这些算法都是完成相同或相似的工作,只是实现不同。它能以法都是完成相同或相似的工作,只是实现不同
10、。它能以相同的方式调用所有算法,减少各种算法类与使用算法相同的方式调用所有算法,减少各种算法类与使用算法类之间的耦合。类之间的耦合。-策略模式的策略模式的Strategy类层次为类层次为Context定义了一系列的可定义了一系列的可供重用的算法或行为。因为继承有助于析取出这些算法供重用的算法或行为。因为继承有助于析取出这些算法的公共功能。的公共功能。3.4 效果与适应性效果与适应性-策略模式也化简了单元测试,因为每一个算法都在一个策略模式也化简了单元测试,因为每一个算法都在一个类内,可以通过自己的接口单独测试。类内,可以通过自己的接口单独测试。w 缺点缺点-客户端必须知道所有的策略类,并自行决
11、定使用哪一个客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。于客户端知道所有的算法或行为的情况。-策略模式造成很多的策略类。有时候可以通过把依赖于策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。可以使用享元模式来减少对象的数量。3.4 效果与适应性效果与适应性w 适用范围适用范围-策略模式就是用来封装算法的。在实践中,我策略模式就是用来封装算法的。在实践中,我们发现可以用它来封装几乎任何类型的规则,们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要再不同情况下应用只要在分析过程中听到需要再不同情况下应用不同的业务规则,就可以考虑使用策略模式处不同的业务规则,就可以考虑使用策略模式处理这种变化的肯能性。理这种变化的肯能性。The End Thanks!