一、定义。
它定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使
用算法的客户。
比如:一个商场的收银软件,搞活动时有的商品打八折,有的商品买XXX元反XXX元,还有的商品正常
收费。那么我们就可以把商品打八折,买XXX元反XXX元和正常收费,这三种收费方式做个封装,抽象出一
个策略类与客户端来交互,不同的商场有不同的活动方式,如果另一个商场是买东西送积分,那么我们只用
增加策略类里面的算法就行了,然后在客户端里面我们用到哪个算法就实例话就行了。不会影响客户端。
二、实现
如下面UML图:
代码:
//抽象出来的算法(策略)
abstract class Stratregy
{
//算法方法
public abstract void AlgorithmInterface();
}
//具体算法A
class ConcreteStrategyA : Stratregy
{
//算法A实现方法
public override void AlgorithmInterface()
{
Console.WriteLine ("实现A算法");
}
}
//具体算法B
class ConcreteStrategyB : Stratregy
{
//算法B实现方法
public override void AlgorithmInterface()
{
Console.WriteLine("实现B算法");
}
}
//具体算法C
class ConcreteStrategyC: Stratregy
{
//算法C实现方法
public override void AlgorithmInterface()
{
Console.WriteLine("实现C算法");
}
}
class Context
{
Stratregy strategy;
public Context(Stratregy strategy)
{
this.strategy = strategy;
}
//上下问接口
public void ContextInterface()
{
strategy.AlgorithmInterface();
}
}
客户端:
static void Main(string[] args)
{
Context context;
//实例化A
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
//实例化B
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
//实例化C
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
Console.Read();
}
}
三、策略模式解析。
策略模式是一种定义一系列算法的方法,从概念来看,所有这些算法完成的都是相同的工作只是实现不同,它可以以相同的方式调用多有的算法,减少各种算法
类与使用算法类之间的耦合。
优点:
1.简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
2.策略模式的Strategy类层次为Context定义了以系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
3.当不同的行为堆在一个类中时,就很难避免使用条件语句来选择合适的行为。利用策略模式就可以将这些行为封装在一个个独立的Strategy类中,可以在
使用这些行为的类中消除条件语句。
4.避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
5.遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量,增加了维护成本。
四、扩展。
策略模式与简单工厂的结合,举个列子就是上面我说过的商场收费
UML如下图:
代码:
现金收费抽象类类(CashSuper)
正常收费类(CashNormal)
打折收费类(CashRebate)
返利收费类(CashReturn)
用单纯的策略模式和策略模式与简单工厂相结合对比:
结合简单工厂后的策略模式后客户端没有了switch代码,减轻了客户端的职责。但是在CashContext里用了switch代码如果增加一个算法还是必须更改
CashContext代码,很让人不爽。没有办法还是得改,不过还可以用反射技术来解决这个问题。
___________________________
反射:提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。简单的说就是一个未知的对象我们可以通过反射来指导这个对象是个什么东西。一个类,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。