设计模式之策略模式

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

    本次原则开放-封闭。

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

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

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

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

  Ø  详解策略模式

    策略模式(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
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值