C# 策略模式详解:解耦算法与调用流程的实例教程
当业务需求中某一操作存在多种等效实现,且需要根据运行时的上下文灵活切换执行路径时,策略模式是最佳选择。该模式的核心在于将算法或行为的定义与其实际使用隔离开来,使得客户端在不修改原有结构的情况下,能够自由替换不同的处理策略。
核心概念与应用场景
策略模式(Strategy Pattern)属于对象行为型设计模式。在软件开发过程中,如果一个类中包含大量判断不同条件的 switch 或 if-else 语句来实现不同功能,会导致该类变得臃肿且难以维护。当新增一种处理逻辑时,不仅需要添加新代码,还容易引入回归缺陷。
解决这一问题的标准做法是:
- 提取公共行为:将多样的实现逻辑从主逻辑中剥离,定义为独立的类。
- 统一接口契约:所有子类必须实现相同的接口方法,确保行为的一致性。
- 依赖倒置:主类只依赖抽象接口,而非具体的实现类。
这使得系统遵循了“开闭原则”(Open Closed Principle),即对扩展开放,对修改关闭。
C# 策略模式实战:球类运动选择
为了清晰演示该模式的结构,我们将构建一个简单的模拟程序:用户可以选择不同的球类(足球、篮球、排球),系统根据选择执行对应特定的 “Play” 动作。
第1步:定义策略接口
首先,我们需要一个契约(接口),它规定了所有具体策略必须包含的方法。在此例中,我们定义了 IBall 接口及其 Play 方法。
public interface IBall
{
void Play();
}
第2步:创建具体策略实现类
接下来,针对每一种具体的球类,分别建立继承自 IBall 的实体类。每个类内部编写特定于该球类的逻辑。
// 足球策略
public class Football : IBall
{
public void Play()
{
Console.WriteLine("我喜欢足球");
}
}
// 篮球策略
public class Basketball : IBall
{
public void Play()
{
Console.WriteLine("我喜欢篮球");
}
}
// 排球策略
public class Volleyball : IBall
{
public void Play()
{
Console.WriteLine("我喜欢排球");
}
}
第3步:构建上下文(Context)管理策略
需要一个环境类来持有接口引用,并提供设置和调用策略的方法。此类不关心具体执行什么逻辑,只负责执行 Play()。
public class SportsMan
{
private IBall ball;
// 注入/设置当前的策略
public void SetHobby(IBall myBall)
{
ball = myBall;
}
// 执行策略中的行为
public void StartPlay()
{
if (ball != null)
{
ball.Play();
}
}
}
第4步:客户端调用与动态切换
在入口程序中,我们可以通过简单的交互让用户决定使用哪种策略。关键在于,客户端直接实例化了具体的 Football 等对象,并将其传递给 SportsMan,从而完成运行时的绑定。
class Program
{
static void Main(string[] args)
{
IBall ball = null;
SportsMan man = new SportsMan();
while (true)
{
Console.WriteLine("选择你喜欢的球类项目(1=足球, 2=篮球, 3=排球,输入其他退出)");
string input = Console.ReadLine();
switch (input)
{
case "1":
ball = new Football();
break;
case "2":
ball = new Basketball();
break;
case "3":
ball = new Volleyball();
break;
default:
return; // 安全退出
}
// 更新策略并执行
man.SetHobby(ball);
man.StartPlay();
}
}
}
模式总结
在上述代码结构中,SportsMan(Context)不再硬编码任何关于足球或篮球的判断逻辑。如果我们未来需要增加“网球”策略,只需新建一个 TennisBall : IBall 类,并在客户端的 switch 分支中添加对应逻辑即可。这种结构大幅提升了代码模块化和维护性,是 C# 项目中应对复杂条件分支的有力工具。
以上就是 C# 策略模式的具体实践与运行结果解析,更多关于 C# 高级应用及设计模式的详细技术资料请持续关注本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









