设计模式之策略模式

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

策略模式的例子使用商场收银再好不过了,商场默认为正常收银;如果有打折,比如是打8折;如果有满减,满100减20;再或者满100送10积分;也可能是打折后满200减20等等这样的很多方式。而这些一个个方式也就是一个个不同的算法,根据策略模式的定义,将这些一个个算法分别封装起来(即有自己的一个个类),然后客户端想怎么用就怎么用。

策略模式三元素:1.Context上下文,用一个属性或者是一个方法来配置,维护一个策略的对象;

        2.策略类(策略接口),定义所有支持算法的接口;

        3.具体策略类,实现了各自具体的算法,继承自策略类(策略接口)。

上下文对象类:

    class StrategyContext
    {
        Strategy strategy;
        public StrategyContext(Strategy strategy)
        {
            this.strategy = strategy;
        }

        public void ContextInterface()
        {
            strategy.AlgorithmInterface();
        }
    }

策略类:

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

策略实现类:

    class StrategyA:Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("我是算法A");
        }
    }

    class StrategyB:Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("我是算法B");
        }
    }

    class StrategyC:Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("我是算法C");
        }
    }

代码都是比较简单的,上下文对象中一个策略抽象类的对象,在构造函数中进行赋值,一个执行策略行为的方法;策略类,只有一个抽象的方法(根据自己的需求可以添加各种方法);策略实现类,和策略类没大差,就是实现了具体的方法。

调用:

            StrategyContext context = new StrategyContext(new StrategyA());
            context.ContextInterface();

            context = new StrategyContext(new StrategyB());
            context.ContextInterface();

            context = new StrategyContext(new StrategyC());
            context.ContextInterface();

看到调用是不是想破口大骂呢,什么破模式,我还不是实例了具体的策略吗,干吗还要传递给上下文对象,最后还不是执行了我策略的方法呢,这里的确是存在问题,不过骚等待我修改。

修改上下文对象类:

 public StrategyContext(string strategyType)
        {
            switch (strategyType)
            {
                case "StrategyA":
                    strategy = new StrategyA();
                    break;
                case "StrategyB":
                    strategy = new StrategyB();
                    break;
                case "StrategyC":
                    strategy = new StrategyC();
                    break;
                default:
                    break;
            }
        }

通过添加了构造参数,然后在内部判断到底实例哪一个策略。

调用:

           StrategyContext context = new StrategyContext("StrategyA");
            context.ContextInterface();

            context = new StrategyContext("StrategyB");
            context.ContextInterface();

            context = new StrategyContext("StrategyC");
            context.ContextInterface();

调用也很简洁,聪明的你是不是发现,怎么有点简单工厂的影子呢,没错,这个简单工厂还真是无处不在呢。

这样只后,如果有新的策略出现,只需添加一个策略类,然后修改下上下文对象中的判断即可。如果亲爱的你不想这么做,没关系,你可以使用反射的方式来创建这个策略类哦,具体不再赘述,可以参考本人的另外一个 抽象工厂模式的文章有介绍。

 

后记(分析):

通过上述的例子我们可以看到,策略模式是一种定义了一系列算法的方法,从概念上来说所有这些类的算法完成的都是相同的工作,只是实现不同而已,它是以相同的方式调用所有的算法(当然前提是策略对象不同哦),减少了各种算法与使用算法类之间的耦合。策略模式的Strategy类为Context定义了一系列的算法或者行为,继承有助于提取出这些算法中的公共功能。策略模式就是用来封装算法的,但是在实践中,我们可以用它来封装几乎任何类型的规则,只要分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

好了,本次模式介绍就结束了,欢迎大家提意见和建议。

posted @ 2013-07-28 11:20  wangyafei_it  阅读(172)  评论(0编辑  收藏  举报