php策略模式核心在于运行时干净切换算法且不污染调用方:策略接口须声明明确输入(如request对象)与统一输出(如result对象),依赖通过构造函数注入,上下文仅持策略接口变量并由外部注入实例,策略选择逻辑应独立为strategyresolver类。

PHP 实现策略模式不是靠“定义接口+多个类”就完事,关键在运行时能否干净地切换算法,且不触发条件分支污染调用方。
策略接口必须声明明确的输入输出契约
很多实现把 execute() 设成无参或返回 void,结果调用方得自己传状态、改全局、读写类属性——这已经违背策略模式“封装变化”的本意。
- 接口应强制接收统一参数类型(如
array $context或专用Request对象),避免各策略自行解析不同结构 - 返回值需一致(如总是
bool表示是否成功,或统一Result对象),否则上层要加instanceof判断 - 别让策略自己去查数据库或读配置——这些依赖应通过构造函数注入,保持策略纯逻辑
上下文类不能持有具体策略类名或 new 操作
常见错误是写成 $this->strategy = new DiscountByVip(); 或用字符串类名 + new $className(),导致无法单元测试、无法动态替换、违反开闭原则。
- 上下文只持有一个策略接口类型变量:
private StrategyInterface $strategy; - 策略实例必须由外部注入(构造函数或 setter),支持 DI 容器接管
- 若需运行时切换,提供
setStrategy(StrategyInterface $strategy),而非setStrategy(string $type)
真实场景中策略选择逻辑常被误放在上下文里
比如在上下文的 calculate() 方法里写一堆 if-else 判定该用哪个策略——这等于把“策略选择”这个新变化点又塞回了上下文,没解耦。
- 策略选择应独立成一个
StrategyResolver类,输入业务上下文(如用户等级、订单金额),输出对应策略实例 - resolver 可基于配置驱动(如 YAML 映射规则)、也可结合策略的
supports($context): bool方法做运行时匹配 - 避免在 resolver 中硬编码
new,优先用容器 get 或工厂方法
策略模式最难的部分从来不是写几个类,而是划清“谁决定用哪个策略”和“谁执行策略”的边界。一旦选择逻辑散落在调用链各处,模式就退化成了带接口的 if-else。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











