2.1 什么是策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
2.2 策略模式包含角色
—抽象策略角色(strategy): 策略类,通常由一个接口或者抽象类实现。
—具体策略角色(ConcreteStrategy):包装了相关的算法和行为。
—环境角色(Context):持有一个策略类的引用,最终给客户端调用
2.3 策略模式UML图
Strategy为抽象类或接口 定义算法方法,然后由ConcreteStategyA来实现具体的算法,而Context维护着Strategy的实例根据客户端来决定调用哪个子类的方法。
三 策略模式代码
抽象策略类定义公共的方法
/// <summary>
/// 抽象策略类
/// 此抽象类提供统一接口或抽象方法
/// </summary>
abstract class Strategy
{
public abstract void PrintName();
}
具体算法类也可以说是 具体策略类 主要是对算法的具体实现
/// <summary>
/// 具体算法实现类
/// </summary>
class ConcreteStrategyA:Strategy
{
public override void PrintName()
{
Console.WriteLine("这是具体策略类A");
}
}
class ConcreteStrategyB:Strategy
{
public override void PrintName()
{
Console.WriteLine("这是具体策略类B");
}
}
class ConcreteStrategyC:Strategy
{
public override void PrintName()
{
Console.WriteLine("这是具体策略类C");
}
}
Context类维护一个Strategy的实例与Strategy之间交互和数据传递
/// <summary>
/// Context 对象 维护对Strategy对象的引用
/// </summary>
class StrategyContent
{
private Strategy _strategy;
public StrategyContent(Strategy strategy)
{
this._strategy = strategy;
}
public void PrintStrategryMethod()
{
_strategy.PrintName();
}
}
客户端类
/// <summary>
/// Client
/// </summary>
class Program
{
static void Main(string[] args)
{
//将具体类的实例传入Context中
StrategyContent a = new StrategyContent(new ConcreteStrategyA());
StrategyContent b = new StrategyContent(new ConcreteStrategyB());
StrategyContent c = new StrategyContent(new ConcreteStrategyC());
a.PrintStrategryMethod();
b.PrintStrategryMethod();
c.PrintStrategryMethod();
Console.Read();
}
}
结果如下:
进一步优化
策略模式写完后会发现,判断用哪个实例的逻辑又回到客户端去了,对于变化我们提倡要进行封装,那怎么处理呢 答案就是 把简单工厂与策略模式结合
只要修改如下两个类即可
1 Context类 注释部分为原来写法
/// <summary>
/// Context 对象 维护对Strategy对象的引用
/// </summary>
class StrategyContent
{
Strategy _strategy;
//public StrategyContent(Strategy strategy)
//{
// this._strategy = strategy;
//}
//用工厂模式处理
public StrategyContent(string type)
{
switch (type)
{
case "A":
_strategy = new ConcreteStrategyA();
break;
case "B":
_strategy = new ConcreteStrategyB();
break;
case "C":
_strategy = new ConcreteStrategyC();
break;
}
}
public void PrintStrategryMethod()
{
_strategy.PrintName();
}
}
2 客户端类 用了简单工厂后已经把判断的逻辑封装到了工厂类中,所以客户端中不再有判断的逻辑, 也就符合了面向对象中的 封装变化 特征。
/// <summary>
/// Client
/// </summary>
class Program
{
static void Main(string[] args)
{
//将具体类的实例传入Context中
//StrategyContent a = new StrategyContent(new ConcreteStrategyA());
//StrategyContent b = new StrategyContent(new ConcreteStrategyB());
//StrategyContent c = new StrategyContent(new ConcreteStrategyC());
//a.PrintStrategryMethod();
//b.PrintStrategryMethod();
//c.PrintStrategryMethod();
Console.Write("输入A,B,C\r\n");
string result = Console.ReadLine();
StrategyContent instance = new StrategyContent(result);
instance.PrintStrategryMethod();
Console.Read();
}
}
结果如下
四 总结
设计模式 先熟悉 再熟练 最后灵活运用!