设计模式(6)---策略模式

  1、策略模式定义:算法

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

  分析:单元测试

  封装的算法自己是一种策略,重要的是这些算法随时可能互相替换的,这就是变化点,而封装变化点是面向对象的一种重要的思惟方式。策略模式定义的这些算法完成的都是相同的工做,只是实现不一样,它能够以相同的方式调用全部的算法,减小了各类算法类与使用算法类之间的耦合。 测试

  

  2、UML类图:this

  

  3、策略模式的基本代码:  spa

class Program
    {
        static void Main(string[] args)
        {
            Contex context;

            context = new Contex(new ConcreteStrategyA());
            context.ContexInterface();

            context = new Contex(new ConcreteStrategyB());
            context.ContexInterface();

            Console.Read();
        }
    }

    abstract class Strategy
    {
        public abstract void AlgorithmInterface();
    }

    class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法A实现");
        }
    }

    class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法B实现");
        }
    }

    class ConcreteStrategyC : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法C实现");
        }
    }

    class Contex
    {
        Strategy strategy;

        public Contex(Strategy strategy)
        {
            this.strategy = strategy;
        }

        public void ContexInterface()
        {
            strategy.AlgorithmInterface();
        }
    }
View Code

 

  4、举例说明:    设计

  功能:在一家商场有三种销售方式:正常价格、打折销售和返现销售,设计一个收银软件,要求能知足上述的销售方式。本例采用策略模式,将三种销售方式封装起来。code

  基本代码: orm

abstract class CashSuper
    {
        public abstract double acceptCash(double money);
    }

    //正常价格
    class CashNormal : CashSuper
    {
        public override double acceptCash(double money)
        {
            return money;
        }
    }

    //打折策略
    class CashRebate : CashSuper
    {
        private double moneyRebate = 1d;

        public CashRebate(string moneyRebate)
        {
            this.moneyRebate = double.Parse(moneyRebate);
        }

        public override double acceptCash(double money)
        {
            return money * moneyRebate;
        }
    }

    //返现策略
    class CashReturn : CashSuper
    {
        private double moneyCondition = 0d;
        private double moneyReturn = 0d;

        public CashReturn(string moneyCondition, string moneyReturn)
        {
            this.moneyCondition = double.Parse(moneyCondition);
            this.moneyReturn = double.Parse(moneyReturn);
        }

        public override double acceptCash(double money)
        {
            double result = money;

            if (money >= moneyCondition)
            {
                result = money - Math.Floor(money / moneyCondition) * moneyReturn;
            }

            return result;
        }
    }

    class CashContext
    {
        private CashSuper cashSuper;

        public CashContext(CashSuper cashSuper)
        {
            this.cashSuper = cashSuper;
        }

        public double GetResult(double money)
        {
            return cashSuper.acceptCash(money);
        }
    }
View Code

  调用方式: 对象

cashContext = new CashContext(new CashRebate("0.8"));
totalPrices = cashContext.GetResult(Convert.ToDouble(this.tbPrice.Text) * Convert.ToDouble(this.tbNumber.Text));

 

  5、策略模式和简单工厂模式结合:

  结合后,实例化具体策略的过程由客户端转移到Context类中。修改后的CashContext: 

class CashContext
    {
        CashSuper cs = null;

        public CashContext(string type)
        {
            switch (type)
            {
                case "正常收费":
                    CashNormal cs0 = new CashNormal();
                    cs = cs0;
                    break;
                case "满300返100":
                    CashReturn cs1 = new CashReturn("300", "100");
                    break;
                case "打八折":
                    CashRebate cs2 = new CashRebate("0.8");
                    cs = cs2;
                    break;
            }
        }

        public double GetResult(double money)
        {
            return cs.acceptCash(money);
        }
    }

  

  6、适用场景:

  一、在一个系统内有不少类,它们完成相同的功能仅在行为上有所区别,策略模式能够动态地选择一种行为。

  二、一个系统的算法使用的数据不让客户端获取。策略模式能够避免客户端涉及到一些复杂的或特别的数据。

  三、若是一个对象有不少的行为,若是不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就能够避免使用难以维护的多重条件选择语句,并体现面向对象设计的概念。

  四、 一个系统须要动态地在几种算法中选择一种。那么这些算法能够包装到一个个的具体算法类里面,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,因为多态性原则,客户端能够选择使用任何一个具体算法类,并只持有一个数据类型是抽象算法类的对象。

 

  7、策略模式优缺点:

  优势:

  一、 简化了单元测试,由于每一个算法都有本身的类,能够经过本身的接口单独测试。
  二、 定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
      三、 遵照大部分GRASP原则和经常使用设计原则,高内聚、低偶合。 

  缺点:

  1. 客户端必须知道全部的策略类,并自行决定使用哪个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道全部的算法或行为的状况。

  2. 策略模式形成不少的策略类。有时候能够经过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例能够被不一样客户端使用。换言之,可使用享元模式来减小对象的数量。

相关文章
相关标签/搜索