首页/开发/代码质量与评审速查/策略模式 Strategy(行为型)
设计原则与模式62 条

策略模式 Strategy(行为型)

把可互换算法封装为独立实现,运行期选择:消除调用方的条件分支,易于新增变体与单测;上下文只持接口,不感知具体算法。

策略模式是什么

策略模式把可互换的算法封装成独立实现,由调用方在运行期选择:调用方不再写按类型分支的判断,新增变体只需加一个实现类,各算法也能单独测试。上下文只持有接口,不感知具体算法,因此实现可以自由替换。

基本信息

意图算法族可替换,运行期选择
收益消除条件分支,算法独立演进
典型实例定价策略、压缩算法、路由规则
结构上下文持有策略接口,多个实现类
关联模式工厂或注册表负责选择实现

典型使用场景

  • 同一计算在不同客户或地区有不同规则
  • 压缩、加密、序列化算法的切换
  • 路由与限流策略按环境调整
  • 校验规则集合可配置
  • 重试与退避策略按下游服务区分

Java 示例

Java 示例
interface Compressor { byte[] compress(byte[] in); }
class GzipCompressor implements Compressor { ... }
class ZstdCompressor implements Compressor { ... }

class Archiver {
    private final Compressor compressor;

    Archiver(Compressor compressor) { this.compressor = compressor; }

    byte[] save(byte[] data) { return compressor.compress(data); }
}

上下文数据怎么给

方案适用代价
整体传上下文策略需要多项数据接口与领域对象耦合
只传必要参数策略只依赖少量输入参数增多时需要重构接口
策略持有配置参数固定而实现不同需注意策略对象是否有状态
策略对象尽量无状态:如果实现里保存中间结果,被复用或并发调用时容易出现难复现的问题;配置类参数应在构造时固定。

选择逻辑放哪里

  • 按类型固定选择:用映射注册表在组装层集中装配
  • 按配置动态选择:读取配置后交给工厂创建
  • 按请求内容选择:在选择器里判断,策略本身保持无状态
  • 按运行环境选择:启动时决定一次,运行期不再变化
为了让策略拿到全部数据而把整个上下文塞进接口,会让接口与领域对象强耦合:日后领域结构一改,所有策略都要跟着改。
如果选择逻辑本身很复杂,它可能就是一个独立职责:抽成选择器或注册表集中管理,比散落在业务代码里逐处判断更容易测试与替换。

易错点

  • 策略对象需要上下文全部数据:接口被迫膨胀,耦合方向变得混乱
  • 只有一种策略仍拆接口:按需引入,简单场景先内联
  • 策略实现里有可变状态:并发复用下出现串数据问题
  • 选择逻辑散落在调用方:新增策略仍要改多处分支,收益被抵消

数据来源与参考

  • 《设计模式》(GoF)· Strategy
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌