策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
环境角色(Context):持有一个Strategy类的引用,本例中为AlgorithmContext。
抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类来实现。此角色给出所有具体策略类所需实现的接口,本例中为Algorithm。
具体策略角色(ConcreteStrategy):包装了相关算法或行为,本例中为CircleAlgorithm、RingAlgorithm。
先定义一个算法的抽象类
public abstract class Algorithm
{
public abstract double[] Calculate();
protected double GetRandom()
{
return new Random(Guid.NewGuid().GetHashCode()).Next(0, 100) / 100.00;
}
protected double[] FillAssay(double[] assay)
{
for (int i = 0; i < assay.Length; i++)
{
assay[i] = GetRandom();
}
return assay;
}
}
再定义几个Algorithm的实体类
/// <summary>
/// 圆形检测
/// </summary>
/// <returns></returns>
public class CircleAlgorithm : Algorithm
{
public override double[] Calculate()
{
//外圆最大直径 外圆最小直径 外圆圆度 外圆平均直径
double[] d_Value = new double[4];
return FillAssay(d_Value);
}
}
/// <summary>
/// 圆环检测
/// </summary>
/// <returns></returns>
public class RingAlgorithm : Algorithm
{
public override double[] Calculate()
{
//外圆最大直径 外圆最小直径 外圆圆度 外圆平均直径 内圆最大直径 内圆最小直径 内圆圆度 内圆平均直径 同心度
double[] d_Value = new double[9];
return FillAssay(d_Value);
}
}
定义一个环境类
public class AlgorithmContext
{
private readonly Algorithm _algorithm;
public AlgorithmContext(Algorithm algorithm)
{
_algorithm = algorithm;
}
public double[] GetTestProperty()
{
return _algorithm.Calculate();
}
}
调用
class Program
{
static void Main(string[] args)
{
AlgorithmContext algorithmContext= new AlgorithmContext(new CircleAlgorithm());
double[] values = algorithmContext.GetTestProperty();
string result = null;
values.ToList().ForEach((x) => { result += x + ","; });
Console.WriteLine("圆形结果为{0}", result);
algorithmContext= new AlgorithmContext(new RingAlgorithm());
values = algorithmContext.GetTestProperty();
result = null;
values.ToList().ForEach((x) => { result += x + ",";});
Console.WriteLine("圆环结果为{0}", result);
Console.Read();
}
}
结果
圆形结果为0.94,0.34,0.4,0.09,
圆环结果为0.2,0.93,0.44,0.67,0.28,0.01,0.83,0.24,0.94,
类图
优点与缺点
策略模式的优点:
- 策略类之间可以自由切换。由于策略类都实现同一个接口,所以使它们之间可以自由切换。
- 易于扩展。增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码。
- 避免使用多重条件选择语句,充分体现面向对象设计思想。
策略模式的缺点:
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这点可以考虑使用IOC容器和依赖注入的方式来解决
- 策略模式会造成很多的策略类。
本文主要借鉴了《Gof设计模式》