🔍 一、策略模式是什么?
策略模式(Strategy Pattern) 是一种行为型设计模式,它定义了一系列算法(策略),把它们一个个封装起来,并且使它们可以互相替换。
这种模式让算法的变化独立于使用它的客户端。
🧠 二、通俗理解
策略模式就像是“选择做事的方法”。
想象你要出行:
你可以选择 开车、骑自行车、打车 或 坐地铁。
这些就是“策略”。
而你自己就是“上下文”——根据情况选择一个出行策略来完成目标。
🧱 三、结构图(UML)
+--------------------+ +----------------------------+
| Context | | Strategy(接口) |
|--------------------| +----------------------------+
| - strategy:Strategy|<---- | + Execute(): void |
|--------------------| +----------------------------+
| + SetStrategy() | ▲
| + ExecuteStrategy()| |
+--------------------+ +----------------------------+
| ConcreteStrategyA |
| + Execute(): void |
+----------------------------+
| ConcreteStrategyB |
| + Execute(): void |
+----------------------------+
🔧 四、角色说明
🧩 五、代码示例(简化版)
例子:支付策略(微信 / 支付宝)
// 策略接口
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
// 具体策略
public class WeChatPay : IPaymentStrategy
{
public void Pay(decimal amount) => Console.WriteLine($"使用微信支付 {amount} 元");
}
public class AliPay : IPaymentStrategy
{
public void Pay(decimal amount) => Console.WriteLine($"使用支付宝支付 {amount} 元");
}
// 上下文
public class PaymentContext
{
private IPaymentStrategy _strategy;
public void SetStrategy(IPaymentStrategy strategy)
{
_strategy = strategy;
}
public void Pay(decimal amount)
{
_strategy.Pay(amount);
}
}
使用:
PaymentContext context = new PaymentContext();
context.SetStrategy(new WeChatPay());
context.Pay(100); // 输出:使用微信支付 100 元
💡 六、适用场景
策略模式适合以下场景:
需要在运行时动态选择不同算法/行为时;
需要避免大量 if-else / switch-case 分支判断;
同一个任务可以有多种处理方式;
希望通过策略类复用行为逻辑时。
✅ 七、优点
❌ 八、缺点
📦 九、常见应用场景
🧭 十、与其他模式的区别
与 状态模式:策略侧重于行为选择,而状态模式强调状态转换和内部变化;
与 工厂模式:工厂负责“创建对象”,策略负责“使用对象行为”。
🔚 总结
实践代码🧭🧭🧭🧭
使用一个线上商城 订单的例子 表述策略模式
using System;
using System.Collections.Generic;
namespace DesignPatternsPractice.Src.Behavioral.StrategyPatternRefactor
{
/// <summary>
/// 启动入口
/// </summary>
public class StrategyPatternDemo
{
static void Main()
{
Order order = new Order(OrderStatus.Shipping, "冰激凌");
// 用 OrderService 来处理与订单相关的业务 (多嵌套了一层)
OrderService orderService = new OrderService(new StrategySelector());
string customerPhone = orderService.GetCustomerSupportPhone(order);
Console.WriteLine($"客服电话为: {customerPhone}");
}
}
#region 核心业务类和接口
/// <summary>
/// 策略接口(改名为更有语义)
/// </summary>
public interface ICustomerSupportStrategy
{
string GetCustomerServicePhone();
}
/// <summary>
/// Shipping 状态的策略实现
/// </summary>
public class ShippingStrategy : ICustomerSupportStrategy
{
public string GetCustomerServicePhone() => "1302020003";
}
public class NotShippedStrategy : ICustomerSupportStrategy
{
public string GetCustomerServicePhone() => "13912345678";
}
public class InTransitStrategy : ICustomerSupportStrategy
{
public string GetCustomerServicePhone() => "13887654321";
}
public class ArrivedStrategy : ICustomerSupportStrategy
{
public string GetCustomerServicePhone() => "13711223344";
}
public class DeliveredStrategy : ICustomerSupportStrategy
{
public string GetCustomerServicePhone() => "13699887766";
}
#endregion
#region 策略选择器(负责根据状态返回正确的策略)
public class StrategySelector
{
// 策略注册表:职责从 OrderService 中提取出来了
private readonly Dictionary<OrderStatus, ICustomerSupportStrategy> _strategyMap;
public StrategySelector()
{
// 字典初始化。可以考虑延迟实例化或使用 DI 容器
_strategyMap = new Dictionary<OrderStatus, ICustomerSupportStrategy>
{
{ OrderStatus.Shipping, new ShippingStrategy() },
{ OrderStatus.NotShipped, new NotShippedStrategy() },
{ OrderStatus.InTransit, new InTransitStrategy() },
{ OrderStatus.Arrived, new ArrivedStrategy() },
{ OrderStatus.Delivered, new DeliveredStrategy() }
};
}
/// <summary>
/// 根据订单状态返回对应的策略
/// </summary>
public ICustomerSupportStrategy Select(OrderStatus status)
{
if (_strategyMap.TryGetValue(status, out var strategy))
{
return strategy;
}
throw new Exception($"无法处理的订单状态: {status}");
}
}
#endregion
#region 业务封装类
/// <summary>
/// 订单服务类:业务层,组合使用策略选择器
/// </summary>
public class OrderService
{
private readonly StrategySelector _strategySelector;
public OrderService(StrategySelector strategySelector)
{
_strategySelector = strategySelector;
}
public string GetCustomerSupportPhone(Order order)
{
var strategy = _strategySelector.Select(order.GetStatus());
return strategy.GetCustomerServicePhone();
}
}
#endregion
#region 数据类和枚举
public class Order
{
private readonly OrderStatus _status;
private readonly string _name;
public Order(OrderStatus status, string name)
{
_status = status;
_name = name;
}
public OrderStatus GetStatus() => _status;
public string GetName() => _name;
}
/// <summary>
/// 订单状态(原 OrderType,更符合语义)
/// </summary>
public enum OrderStatus
{
Shipping,
NotShipped,
InTransit,
Arrived,
Delivered
}
#endregion
}