策略模式
策略模式(Strategy Pattern)
定义
策略模式(Strategy Pattern)是行为型设计模式的一种,它定义算法家族并分别封装,使其可以相互替换,且算法的变化独立于使用它的客户端。该模式通过将算法与对象解耦来实现不同算法的灵活切换。
核心思想
- 封装变化:将可能变化的算法部分独立出来。
- 分离职责:将算法定义与使用解耦,避免代码中大量条件分支。
- 面向接口编程:通过接口规范算法行为
- 运行时动态切换:支持在程序执行期间灵活选择算法
- 开闭原则实践:新增算法无需修改既有系统
模式结构

策略模式包含三个核心角色:
| 角色 | 职责说明 |
|---|---|
| IStrategy | 策略接口,声明所有支持的算法方法 |
| ConcreteStrategy | 具体策略实现类,实现接口定义的具体算法(至少包含两个不同实现) |
| Context | 上下文类,持有策略引用,通过组合方式使用策略,提供策略修改接口 |
主要解决的问题
- 消除条件分支:避免在代码中大量使用if-else或switch-case判断不同算法。
- 算法复用困难:避免相似算法在多个类中重复实现
- 灵活扩展算法:新增算法时无需修改原有代码,符合开闭原则。
- 算法独立变化:不同算法可以独立演进,互不影响。
代码示例
场景:
电商系统根据不同促销策略计算订单折扣。
// 策略接口
public interface IDiscountStrategy
{
decimal ApplyDiscount(decimal originalPrice);
}
// 具体策略实现
public class NoDiscount : IDiscountStrategy
{
public decimal ApplyDiscount(decimal price) => price;
}
public class PercentageDiscount : IDiscountStrategy
{
private readonly decimal _percentage;
public PercentageDiscount(decimal percentage) => _percentage = percentage;
public decimal ApplyDiscount(decimal price) => price * (1 - _percentage / 100);
}
public class CashRebate : IDiscountStrategy
{
private readonly decimal _rebateAmount;
public CashRebate(decimal amount) => _rebateAmount = amount;
public decimal ApplyDiscount(decimal price) => Math.Max(0, price - _rebateAmount);
}
// 上下文类
public class PricingContext
{
private IDiscountStrategy _strategy;
public void SetStrategy(IDiscountStrategy strategy) => _strategy = strategy;
public decimal CalculatePrice(decimal originalPrice)
{
return _strategy?.ApplyDiscount(originalPrice) ?? originalPrice;
}
}
// 客户端调用
var context = new PricingContext();
var productPrice = 200.00m;
// 使用普通策略
context.SetStrategy(new NoDiscount());
Console.WriteLine($"原价: {context.CalculatePrice(productPrice):C}");
// 切换为8折策略
context.SetStrategy(new PercentageDiscount(20));
Console.WriteLine($"折扣价: {context.CalculatePrice(productPrice):C}");
// 切换为满减策略
context.SetStrategy(new CashRebate(50));
Console.WriteLine($"满减价: {context.CalculatePrice(productPrice):C}");
总结
优点
- 解耦性强:算法与使用场景分离,便于独立维护。
- 可扩展性高:新增策略无需修改现有代码。
- 运行时灵活性:支持动态切换策略。
缺点
- 策略类数量增加:每个算法一个类,可能增加系统复杂度。
- 客户端需了解策略差异:需要知道不同策略的区别以正确选择。
适用场景
- 需要多种算法变体(如支付方式、排序算法、折扣规则)。
- 需要动态切换算法。
- 需要隐藏复杂算法实现细节。
性能注意
- 若策略简单且数量少,直接使用条件判断可能更高效。
- 对于频繁创建的策略对象,可结合工厂模式或享元模式优化。

浙公网安备 33010602011771号