静态局部策略模式指用static工厂方法+无状态策略类实现算法切换,Context不持策略引用、保持无状态,每次调用独立指定策略,确保并发安全与测试隔离。

静态局部策略模式不是标准设计模式术语,实际想表达的是:用 static 工厂方法 + 无状态策略类 实现算法切换,同时避免在 Context 实例中保存策略引用、不依赖实例生命周期。
核心思路:策略由调用方决定,Context 不持引用
传统 Context 类通常持有 strategy 成员变量,这会把策略绑定到实例上。而“静态局部”本质是让策略选择发生在方法调用时,每次调用都可独立指定策略,Context 自身保持无状态。
- Context 类不声明 private $strategy 属性
- 所有策略执行方法都接收策略对象作为参数(或通过 static 工厂获取)
- 策略类自身不保存运行时状态(如计数器、缓存句柄),确保 new 一次就安全用一次
PHP 示例:解析器按格式动态选策略
假设需解析 JSON / XML / CSV,但不想让 Parser 实例记住上次用了哪种格式:
interface ParserStrategy {
public function parse(string $input): array;
}
class JsonParser implements ParserStrategy {
public function parse(string $input): array {
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new InvalidArgumentException('Invalid JSON');
}
return $data ?? [];
}
}
class XmlParser implements ParserStrategy {
public function parse(string $input): array {
// 简化示意,实际用 simplexml_load_string 或 DOM
return ['xml' => trim($input)];
}
}
class Parser {
// 静态工厂:只返回新策略实例,不缓存、不单例
public static function for(string $format): ParserStrategy {
return match($format) {
'json' => new JsonParser(),
'xml' => new XmlParser(),
default => throw new InvalidArgumentException("Unsupported format: {$format}"),
};
}
// 关键:parse 方法不依赖 $this->strategy,而是由调用方传入或现场获取
public function parse(string $input, string $format): array {
return self::for($format)->parse($input);
}
}
- Parser 实例本身没有状态,new Parser() 可复用、可丢弃、可并发使用
- 每次 parse 调用都通过 static::for() 获取新策略实例,彼此隔离
- 若策略需外部依赖(如 HTTP client),应通过构造函数注入,而非在 for() 里 new 它们
为什么不用单例或属性缓存策略
因为那会引入隐式状态:
- 如果 Parser 里存了 $this->strategy = new JsonParser(),后续调用 parse() 却没重设,就可能误用旧策略
- 若多个协程/请求共用同一 Parser 实例,策略切换可能互相干扰(尤其策略带内部状态时)
- static 工厂配合无状态策略,天然支持并发安全和测试隔离
进阶:支持运行时策略配置而不改代码
当策略选择逻辑变复杂(比如根据文件头 magic bytes 判断格式),可把判断逻辑外移,仍保持 Parser 干净:
- 写一个 FormatDetector 类,输入内容,输出 'json'/'xml'/etc
- 业务层先调用 detector→getFormat($raw),再传给 Parser::parse($raw, $format)
- Parser 本身不关心“怎么猜格式”,只负责“按指定格式解析”——职责清晰

















