设计模式之策略模式 Strategy Pattern
V1.0
核心概念
策略模式是一种行为型设计模式,其核心思想是业务类执行某个动作时,可以使用该动作的不同的实现,并在程序运行中可以切换使用该动作的不同的实现。
不同的动作的实现被封装为不同的类,这些具体实现类继承统一的接口,因此业务类可以持有任一动作具体实现,并可以对其进行替换。
角色
- Strategy(策略接口):定义了动作的统一接口,具体策略需要实现该接口。
- ConcreteStrategy(具体策略):实现了策略接口,不同的具体策略实现了同一动作的不同实现。
- Context(上下文):持有具体策略的引用,在业务中执行具体策略,并可以更换不同的具体策略,以使用同一动作的不同的实现方式。
代码示例
csharp
/// <summary>
/// 交通方式策略接口,定义了动作的统一接口
/// </summary>
public interface ITransportationMode
{
public void Travel();
}
/// <summary>
/// 具体策略,乘坐飞机
/// </summary>
public class ConcreteModeAirplane:ITransportationMode
{
public void Travel()
{
Console.WriteLine("Travel by airplane");
}
}
/// <summary>
/// 具体策略,乘坐火车
/// </summary>
public class ConcreteModeTrain : ITransportationMode
{
public void Travel()
{
Console.WriteLine("Travel by train");
}
}
/// <summary>
/// 具体策略,乘坐长途汽车
/// </summary>
public class ConcreteModeCoach : ITransportationMode
{
public void Travel()
{
Console.WriteLine("Travel by coach");
}
}
/// <summary>
/// 上下文类,可以使用不同的出行方式出行
/// </summary>
public class ContextTravelPlan
{
/// <summary>
/// 出行方式
/// </summary>
public ITransportationMode mean;
public ContextTravelPlan(ITransportationMode mean)
{
this.mean = mean;
}
/// <summary>
/// 更换策略,即出行方式
/// </summary>
/// <param name="newMean"></param>
public void setMean(ITransportationMode newMean)
{
this.mean = newMean;
}
public void travelTo(string place)
{
mean.Travel();
Console.WriteLine($"Traveled to {place}");
}
}
public class Program
{
public static void Main(string[] arg)
{
//建立具体策略对象
ConcreteModeAirplane meanAirplane = new();
ConcreteModeTrain meanTrain = new();
ConcreteModeCoach meanCoach = new();
//建立旅行计划上下文类
ContextTravelPlan ctp = new(meanAirplane);
//使用飞机方式出行
ctp.travelTo("Shanghai");
//更换策略,使用火车出行方式
ctp.setMean(meanTrain);
//使用火车方式出行
ctp.travelTo("Chongqing");
//更换策略,使用长途汽车出行方式
ctp.setMean(meanCoach);
//使用长途汽车出行
ctp.travelTo("Jinan");
}
}
程序运行结果
Travel by airplane
Traveled to Shanghai
Travel by train
Traveled to Chongqing
Travel by coach
Traveled to Jinan
代码讲解
- ITransportationMode接口:策略接口,定义了交通方式的统一接口
Travel
,具体的交通方式需要实现这个接口。 - ConcreteModeAirplane类:具体策略,实现了交通方式接口
Travel
,为乘坐飞机出行,接口实现中输出了乘坐飞机出行的信息。 - ConcreteModeTrain类:具体策略,实现了交通方式接口
Travel
,为乘坐火车出行,接口实现中输出了乘坐火车出行的信息。 - ConcreteModeCoach类:具体策略,实现了交通方式接口
Travel
,为乘坐长途汽车出行,接口实现中输出了乘坐长途汽车出行的信息。 - ContextTravelPlan类:上下文类,是具体的业务逻辑,构造时使用具体出行方式对象(具体策略对象)构建,并可以使用
setMean
方法替换具体出行方式(具体策略)。toTravel
方法是上下文类的具体的业务逻辑,其中使用其持有的出行方式mean
,出行到指定的地方。 - Program类:客户端代码,创建了具体出行方式(具体策略),使用飞机出行方式
meanAirplane
创建了出行上下文类,执行出行动作。更换出行方式,即具体策略,再次进行出行动作,重复2次。
适用范围
- 当一个动作可能有多种实现,并且需要在不同时间修改使用不同的动作实现时。
- 将来可能添加新的动作实现的场景,使用策略模式可以不修改现有的代码。