您的位置:首页 > 其它

设计模式你怎么看?--策略模式

2014-04-04 08:27 351 查看

一前言

把自己学习的结果用文章表现出来并留做日后参考~今天要学习的模式为"策略模式"!

设计模式你怎么看?--简单工厂模式

设计模式你怎么看?--抽象工厂模式

设计模式你怎么看?--工厂方法模式

二 策略模式介绍

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();
}
}


结果如下



四 总结

  设计模式 先熟悉 再熟练 最后灵活运用!

"代码虽易,写好不易 且写且珍惜"

本人水平有限,如有不对之处还请指出 谢谢~

如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~

如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: