php 装饰器模式应用
PHP 装饰器模式:不写死继承链,动态给业务对象“穿外套”
很多 PHP 开发者遇到“功能叠加”需求时,习惯性地开新类去继承基类。三层五层下来,继承树长得像盘根错节的老树根,改一处动全身,测试覆盖率也跟着跳水。其实 PHP 原生完全支持用接口加组合的方式落地装饰器模式,不用等框架搭中间件,自己就能写出轻量的动态扩展方案。
装饰器的核心逻辑很直白:在不触碰原对象的前提下,往它身上追加行为。PHP 没有语法糖式的注解装饰器,得靠显式的类组合与委托机制来完成。看一套可直接复用的高内聚结构。
先定契约,所有被包装的对象必须认领同一个接口标识:
interface ResponseTransformer {
public function transform(string $rawJson): array;
}
基础实现只负责解析业务 payload,不掺杂任何横切关注点。接下来编写装饰器基类,它必须实现同一接口,并将核心动作委托给内部持有的对象:
abstract class BaseDecorator implements ResponseTransformer {
protected ResponseTransformer $target;
public function __construct(ResponseTransformer $target) {
$this->target = $target;
}
// 关键步骤:子类仅重写需要干预的方法,默认保持委托链路畅通
public function transform(string $rawJson): array {
return $this->target->transform($rawJson);
}
}
子类按需注入逻辑即可。比如套一层字段脱敏壳,只需在重写方法里先调父级转换,再对黑名单字段做掩码处理;套一层性能监控壳,就在调用前后掐表记录耗时。这种写法把“核心逻辑”和“附加逻辑”彻底解耦,新增需求就像热插拔插件,不用动现有文件。
实际对接第三方接口时,装饰器最常落在响应清洗环节。原始返回的数据结构经常带着冗余嵌套或脏字符,硬写在主控流程里迟早污染可读性。把清洗规则拆成独立装饰器层层包裹,请求进来走主干,出去前自动过一遍格式化流水线。
链条拉长了难免引发性能焦虑。多次 new 与方法转发确实会吃内存和栈空间。应对思路很务实:控制同级装饰器数量,单条链路不超过三个同类节点;频繁进出的热点路由,建议将稳定配置的装饰树提前序列化或做成工厂单例,避开运行时反复组装。 见过不少团队为了追求“绝对开放”,把每个校验、缓存、埋点都独立成一个装饰类,压测时发现 CPU 空转全耗在对象实例化上。灵活的前提是懂得收敛。
配合现代 PHP 特性,可以在构造函数直接用类型提示与属性提升压缩样板代码。单元测试也别拖进整个请求周期,把裸接口扔进去,逐层包裹后只断言“原对象未变异,新行为准确挂载在指定位置”。隔离底层依赖后,装饰器本身的边界几乎零摩擦。
装饰器不是拿来替代策略或工厂的,它在处理“横向能力叠加”时,比粗暴的子类膨胀要干净利落。把动态封装的思维嵌进日常迭代,下次碰到需求蔓延,先试试套个壳再交出去。系统的可维护性,往往就藏在这些不动声色的设计取舍里。


还没有评论,来说两句吧...