策略模式(Strategy Pattern)

来源:互联网 发布:gta5女性捏脸数据 编辑:程序博客网 时间:2024/05/17 22:31
策略模式(Strategy Pattern)
策略模式定义了一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
别名:Policy(方针)
结构:

代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy{    abstract class Strategy    {        public abstract void AlgorithmInterface();    }    class ConcreteStrategyA : Strategy    {        public override void AlgorithmInterface()        {            Console.WriteLine("Algorithm A implementation");        }    }    class ConcreteStrategyB : Strategy    {        public override void AlgorithmInterface()        {            Console.WriteLine("Algorithm B implementation");        }    }    class ConcreteStrategyC : Strategy    {        public override void AlgorithmInterface()        {            Console.WriteLine("Algorithm C implementation");        }    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy{    class Context    {        private Strategy strategy;        public Context(Strategy strategy)        {            this.strategy = strategy;        }        public void ContextInterface()        {            strategy.AlgorithmInterface();        }    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy{    class Program    {        static void Main(string[] args)        {            Context context;            context = new Context(new ConcreteStrategyA());            context.ContextInterface();            context = new Context(new ConcreteStrategyB());            context.ContextInterface();            context = new Context(new ConcreteStrategyC());            context.ContextInterface();            Console.ReadKey();        }    }}

参与者:
 Strategy( 策略 )
— 定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
• ConcreteStrategy(具体策略)
— 以Strategy接口实现某具体算法。
• Context(上下文)
— 用一个ConcreteStrategy对象来配置。
维护一个对Strategy对象的引用。
— 可定义一个接口来让Strategy访问它的数据。

效果:
1)相关算法系列Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
2) 一个替代继承的方法。继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来 , 从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 ,  它们之间的唯一差别是它们所使用的算法或行为。将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。
3) 消除了一些条件语句。Strategy模式提供了用条件语句选择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时 ,  很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的Strategy类中消除了这些条件语句。

实现:
1)定义Strategy和Context接口

一种办法是让Context将数据放在参数中传递给Strategy操作——也就是说, 将数据发送给Strategy。这使得Strategy和Context解耦。另一种办法是让Context将自身作为一个参数传递给Strategy, 该Strategy再显式地向该Context请求数据。或者,Strategy可以存储对它的Context的一个引用, 这样根本不再需要传递任何东西。

2)将Strategy作为模板参数

template <class AStrategy>class Context {public    void Operation()    {        theStrategy.DoAlgorithm();    }private:    AStrategy theStrategy;}class MyStrategy{public:    void DoAlgorithm();}Context<MyStrategy> myContext;
可以在编译时选择Strategy,不需要在运行时改变,提高效率。

3)使Strategy对象称为可选

实际应用代码:

商场购物结账,根据不同的付账方式,选择不同的计算策略。CashContext用到了简单工厂,下面代码中策略模式与简单工厂相结合,降低了代码的耦合性。

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy1{    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 = 0.0d;        private double moneyReturn = 0.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;        }    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy1{    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 "打8折":                    CashRebate cr2 = new CashRebate("0.8");                    cs = cr2;                    break;            }        }        public double GetResult(double money)        {            return cs.acceptCash(money);        }    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy1{    class Program    {        static void Main(string[] args)        {            double totalPrices = 100d;            string cashType = "打8折";                    CashContext csuper = new CashContext(cashType);            totalPrices = csuper.GetResult(totalPrices);            Console.ReadKey();        }    }}

参考《设计模式》、《大话设计模式》,进行整理。

0 0
原创粉丝点击