设计模式之策略模式
策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式的例子使用商场收银再好不过了,商场默认为正常收银;如果有打折,比如是打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定义了一系列的算法或者行为,继承有助于提取出这些算法中的公共功能。策略模式就是用来封装算法的,但是在实践中,我们可以用它来封装几乎任何类型的规则,只要分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
好了,本次模式介绍就结束了,欢迎大家提意见和建议。