设计模式之策略模式

来源:互联网 发布:金蝶数据库可以恢复吗 编辑:程序博客网 时间:2024/06/05 02:16

    设计模式中常常会提到一个设计原则,那就是开放-封闭原则,《大话设计模式》中设计了六种原则,分别为单一职责原则、开放-封闭原则、依赖倒转原则、里氏代换原则、迪米特法则、合成/聚合复用原则。以后的博客中会一一涉及,现在就不一一介绍了。

    本次原则开放-封闭。

    所谓开放封闭原则就是软件实体应该对扩展开发,而对修改封闭。开放封闭原则是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化,降低耦合,而开放封闭原则正是对这一目标的最直接体现。

    我们说什么样的代码是好的,很多人都会认为增加功能或者别的什么,代码的修改量越少,这样的代码越是优秀。所以关闭修改,开放扩展在设计模式中几乎每一个模式都在贯穿着。看下面讲的这个就有。

    我们以现实生活的例子为例,商场促销,手段各部相同,比如打折销售、买一赠一、捆绑销售、还有就是量多减价等等。这称之为商场销售之道,也是一种策略。

    先提出这个概念,我们在慢慢讲解:

  Ø  详解策略模式

    策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

    u  结构如图:


    u  角色

      三个角色:

        l  Context(环境类)

        l  Strategy(抽象策略类)

        l  ConcreteStrategy(具体策略类)

    u  实现

abstract class AbstractStrategy{    public abstract void Algorithm(); //声明抽象算法}class ConcreteStrategyA : AbstractStrategy {//算法的具体实现public override void Algorithm() {    //算法A}}class ConcreteStrategyB : AbstractStrategy {//算法的具体实现public override void Algorithm() {    //算法B}}……class Context{Strategy strategy; Public Context (Strategy strategy)    //初始化时,传入具体的策略对象{    this.strategy = strategy;}//根据具体的策略对象,调用策略类中的算法public void ContextInterface() {    strategy.AlgorithmInterface();}}

    u  对比

      客户端中策略模式(含简单工厂)与简单工厂模式的不同点在于:

     ²  简单工厂模式:

CashSuper  csuper=CashFactory.createCashAccept(cbxType.SelectedItem.ToString());…=csuper.GetResult(…)

     ²  策略模式(含简单工厂):

CashContext  csuper=new CashContext(cbxTye.SelectedItem.ToString());…=csuper.GetResult(…);

    简单工厂:可以看出简单工厂的缺点非常明显,那就是其客户端的某个改动直接影响的就是工厂类,这样使得程序的修改太大,同时也违背了开放-封闭原则。

    优点就是可以将实例化具体策略过程由客户端转移到Context中。

    比如:

class CashContext    {        CashSuper cs = null;        public CashContext(string type)        {            switch (type)            {                case"正常收费":                    CashNormal cs0 = new CashNormal();                    cs=cs0 ;                    break ;                case "满300返100":                    CashReturn cr1 = new CashReturn("300","100");                    cs = cr1;                    break;                case "打八折":                    CashRebate cr2 = new CashRebate("0.8");                    cs = cr2;                    break;            }        }        public double GetResult(double money)        {            return cs.acceptCash(money);        }

    策略模式与简单工厂的集合使得开放-封闭原则得到很好的应用和实现。

 

    客户端程序

 double total = 0.0d;        private void button1_Click(object sender, EventArgs e)        {            CashContextcsuper = new CashContext(cbxtype.SelectedItem.ToString());            double totalPrices = 0d;            totalPrices =csuper .GetResult (Convert.ToDouble (txtPrice.Text ))* (Convert.ToDouble(txtNum .Text));            total=total+totalPrices ;        }

    可以看出此时的客户端只需要认识CashContext类即可,只需要在客户端实例化其CashContext的对象即可。

    此时不免想起了工厂方法,工厂方法里为了避免大部分代码的修改,采用是把简单工厂的内部逻辑判断移到了客户端代码,使得只需要更改相应的客户端就可以了。

计算器实现客户端的一句代码。

    IFactory operFactory=new AddFactory();

    这样只需修改AddFactory便可以实现不同的运算。减少了代码的修改,开放了扩展。


0 0