设计模式Design Pattern,一个已经被大家聊烂的话题,好多年前都已经看到,但一直没有看懂,可能是自己水平有限,还达不到那个高度。时隔几年,再次捡起,哦,竟然有了那么一点眉目了~
设计模式的书,也买了好几本了,从最开始的《大话设计模式》,以互动交流的方式进行阐述;《Head First Design Pattern》,Head First系列最经典的设计模式书之一;以及《ASP.NET 设计模式》等等。
达不到一个层次,看这些东西的确困难,现在翻开来看,竟然也能看懂了,那就慢慢看吧,顺便把自己的心得体验放到这里~
以上,是为序~~~
今天先来聊的是策略模式Strategy Pattern,先来一段标准的GoF描述:
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
我的理解就是,通过具体的策略类,来实现接口中定义的方法,这些方法在外部看来是一样的,这样,在客户端进行调用的时候,就不需要关注具体策略类的区别,而直接进行正常调用即可。
还是用代码来说明这些事情,先贴上一个标准的类图:
接下来,我们用C#的代码来进行实现:
1、 定义IStrategy接口
namespace StrategyPattern
{
/// <summary>
/// 策略接口
/// </summary>
public interface IStrategy
{
/// <summary>
/// 算法接口
/// </summary>
void AlgorithmInterface();
}
}
2、分别实例化该接口
namespace StrategyPattern
{
/// <summary>
/// 策略A
/// </summary>
public class StrategyA : IStrategy
{
public void AlgorithmInterface()
{
Console.WriteLine("算法A中的具体实现");
}
}
/// <summary>
/// 策略B
/// </summary>
public class StrategyB : IStrategy
{
public void AlgorithmInterface()
{
Console.WriteLine("算法B中的具体实现");
}
}
/// <summary>
/// 策略C
/// </summary>
public class StrategyC : IStrategy
{
public void AlgorithmInterface()
{
Console.WriteLine("算法C中的具体实现");
}
}
}
3、创建调用接口的Context类
namespace StrategyPattern
{
public class Context
{
/// <summary>
/// 声明接口
/// </summary>
protected IStrategy strategy;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="_strategy">注入的参数</param>
public Context(IStrategy _strategy)
{
strategy = _strategy;
}
/// <summary>
/// 具体实现方法
/// 在里面调用策略中的算法接口
/// </summary>
public void DoSomething()
{
strategy.AlgorithmInterface();
}
}
}
4、客户端进行调用
namespace StrategyPattern
{
internal class Program
{
private static void Main(string[] args)
{
//第一个实例,使用了策略A
Context context1 = new Context(new StrategyA());
context1.DoSomething();
//第二个实例,使用了策略B
Context context2 = new Context(new StrategyC());
context2.DoSomething();
Console.Read();
}
}
}
5、查看运行结果
以上是对策略模式的具体实现,这里只是最简单的例子,实际使用中,可能会比这更复杂,但只要简单的可以理解,复杂的无非就是多了一下接口和方法而已。
对该模式的适用场景,主要如下:
- 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
- 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
- 对客户(
Context
)隐藏具体策略(算法)的实现细节,彼此完全独立。
策略模式的优缺点
优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
2、必须了解所有的strategy,了解各个strategy之间的不同点,这样才能选择一个合适的strategy。对使用者也有一些挑战。
上述观点仅代表个人意见,大家可对此进行补充讨论。