Strategy Pattern (策略模式)
所谓 Strategy Pattern 的精神,就是将策略 (算法) 封装为一个对象,易于相互替换,如同 USB 设备一样可即插即用;而不是将策略、具体的算法和行为,硬编码在某个类或客户程序中,导至事后的修改和扩展不易。
若有多种「策略」,就将这些个策略,和这些策略的算法、行为,封装在各个类中,并让这些类,去继承某个公用的抽象类或接口。接着在客户程序中,就可动态引用,且易于更换这些不同的「策略」,不会因为日后添加、修改了某一个「策略」,就得重新修改、编译多处的源代码。此即为一种「封装变化点」的做法,将常会变化的部分进行抽象、定义为接口,亦即实现「面向接口编程」的概念。且客户程序 (调用者) 只须知道接口的外部定义即可,具体的实现则无须理会。
The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
- Design Patterns: Elements of Reusable Object-Oriented Software
Strategy Pattern 适用的情景:
- 应用中的许多类,在解决某些问题时很相似,但实现的行为有所差异。比如:不同功能的程序,都可能要用到「排序」算法。
- 根据运行环境的不同,需要采用不同的算法。比如:在手机、PC 计算机上,因硬件等级不同,必须采用不同的排序算法。
- 针对给定的目的,存在多种不同的算法,且我们可用代码实现算法选择的标准。
- 需要封装复杂的数据结构。比如:特殊的加密算法,客户程序仅需要知道调用的方式即可。
- 同上,算法中的罗辑和使用的数据,应该与客户程序隔离时。
图 1 这张为很多书籍和文档都曾出现过的 Strategy 经典 Class Diagram
01_Shell.ASPx.cs
using System;
using com.cnblogs.WizardWu.sample01;
//客户程序
public partial class _01_Shell : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//执行对象
Context context;
context = new Context(new ConcreteStrategyA());
Response.Write(context.ContextInterface() + "
");
context = new Context(new ConcreteStrategyB());
Response.Write(context.ContextInterface() + "
");
context = new Context(new ConcreteStrategyC());
Response.Write(context.ContextInterface() + "
");
}
}
namespace com.cnblogs.WizardWu.sample01
{
//抽象算法类 (亦可用接口)。定义了所有策略的公共接口
abstract class Strategy
{
//算法需要完成的功能
public abstract string AlgorithmInterface();
}
//具体算法类A
class ConcreteStrategyA : Strategy
{
//算法A实现方法
public override string AlgorithmInterface()
{
return "算法A实现";
}
}
//具体算法类B
class ConcreteStrategyB : Strategy
{
//算法B实现方法
public override string AlgorithmInterface()
{
return "算法B实现";
}
}
//具体算法类C
class ConcreteStrategyC : Strategy
{
//算法C实现方法
public override string AlgorithmInterface()
{
return "算法C实现";
}
}
//执行对象。需要采用可替换策略执行的对象
class Context
{
Strategy strategy;
public Context(Strategy strategy) //构造函数
{
this.strategy = strategy;
}
//执行对象依赖于策略对象的操作方法
public string ContextInterface()
{
return strategy.AlgorithmInterface();
}
}
} // end of namespace
/*
结行结果:
算法A实现
算法B实现
算法C实现
*/
NET技术:C# Design Patterns (2) - Strategy,转载需保留来源!
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。