C# 策略模式深度解析:从原理到实战
·
一、策略模式的核心思想
策略模式(Strategy Pattern)是一种行为型设计模式,其核心目标是将算法族封装成独立类,使它们能在运行时动态替换。通过该模式,客户端代码无需依赖具体算法实现,只需通过统一的接口调用,即可灵活切换不同策略,同时满足开闭原则(对扩展开放、对修改关闭)。
核心优势:
- 解耦算法与业务逻辑:避免大量条件分支(如
if-else或switch),提升代码可维护性。 - 动态扩展性:新增策略只需添加新类,无需修改现有代码。
- 复用性与测试性:策略类可独立测试,且能被多个上下文复用。
二、策略模式的结构与角色
- IStrategy(策略接口)
定义所有算法的公共契约,例如Execute()或Apply()方法。 - ConcreteStrategy(具体策略)
实现接口的具体算法类(如折扣策略A、折扣策略B)。 - Context(上下文)
持有策略对象的引用,通过接口调用具体算法,支持运行时切换策略。
三、C# 实现示例:电商促销系统
假设电商平台需根据促销类型(无折扣、百分比折扣、固定金额折扣)计算订单价格。以下是代码实现:
1. 定义策略接口
// 促销策略接口
public interface IPromotionStrategy
{
decimal ApplyPromotion(decimal originalPrice);
}
2. 实现具体策略类
// 无折扣策略
public class NoDiscountStrategy : IPromotionStrategy
{
public decimal ApplyPromotion(decimal originalPrice)
{
return originalPrice; // 原价
}
}
// 百分比折扣策略
public class PercentageDiscountStrategy : IPromotionStrategy
{
private readonly decimal _discountPercentage;
public PercentageDiscountStrategy(decimal discountPercentage)
{
_discountPercentage = discountPercentage;
}
public decimal ApplyPromotion(decimal originalPrice)
{
return originalPrice * (1 - _discountPercentage / 100);
}
}
// 固定金额折扣策略
public class FixedAmountDiscountStrategy : IPromotionStrategy
{
private readonly decimal _discountAmount;
public FixedAmountDiscountStrategy(decimal discountAmount)
{
_discountAmount = discountAmount;
}
public decimal ApplyPromotion(decimal originalPrice)
{
return originalPrice - _discountAmount;
}
}
3. 上下文类(订单管理)
public class Order
{
private IPromotionStrategy _promotionStrategy;
private decimal _originalPrice;
public Order(decimal originalPrice, IPromotionStrategy promotionStrategy)
{
_originalPrice = originalPrice;
_promotionStrategy = promotionStrategy;
}
// 动态切换策略
public void SetPromotionStrategy(IPromotionStrategy promotionStrategy)
{
_promotionStrategy = promotionStrategy;
}
public decimal CalculateFinalPrice()
{
return _promotionStrategy.ApplyPromotion(_originalPrice);
}
}
4. 客户端调用
var order = new Order(100.0m, new NoDiscountStrategy());
Console.WriteLine($"无折扣价格:{order.CalculateFinalPrice()}"); // 输出:100.0
order.SetPromotionStrategy(new PercentageDiscountStrategy(20)); // 20%折扣
Console.WriteLine($"百分比折扣价格:{order.CalculateFinalPrice()}"); // 输出:80.0
order.SetPromotionStrategy(new FixedAmountDiscountStrategy(30)); // 固定减30
Console.WriteLine($"固定金额折扣价格:{order.CalculateFinalPrice()}"); // 输出:70.0
四、策略模式的高级应用场景
- 与工厂模式结合
通过工厂类根据条件动态创建策略对象(如根据用户类型选择优惠策略)。 - 依赖注入(DI)
在 ASP.NET Core 中,通过依赖注入容器注册策略,实现自动切换(如services.AddTransient<IPromotionStrategy, PercentageDiscountStrategy>())。 - Lambda 表达式简化
使用委托(Delegate)替代接口,减少类定义(适用于简单策略)public class Calculator { public decimal Calculate(Func<decimal, decimal> strategy, decimal price) { return strategy(price); } } // 调用示例 var result = new Calculator().Calculate(p => p * 0.8m, 100.0m); // 直接传递Lambda
五、策略模式与相似模式对比
- 状态模式
- 策略模式:客户端主动选择算法。
- 状态模式:状态自动切换行为(如订单状态流转)。
- 装饰器模式
- 策略模式:替换整个算法。
- 装饰器模式:叠加附加功能(如日志+缓存)。
六、优缺点总结
优点:
- 消除条件分支,提升代码可读性。
- 支持动态扩展,符合单一职责原则。
缺点:
- 类数量可能激增(每个策略对应一个类)。
- 客户端需理解策略差异,增加使用成本。
七、实际案例扩展
- 支付网关选择
根据用户地理位置动态切换支付方式(如支付宝、PayPal)。 - 图像处理算法
支持多种压缩算法(JPEG、PNG)的运行时切换。 - 游戏AI行为
根据敌人类型切换攻击策略(如近战、远程)。
八、总结
策略模式通过算法封装与动态替换,为复杂业务逻辑提供了优雅的解决方案。在C#中,其实现灵活且易于集成至现代框架(如依赖注入)。无论是电商促销、支付系统还是游戏开发,合理运用策略模式均可显著提升代码质量与可维护性。
更多推荐


所有评论(0)