真正能落地的设计模式需明确问题、创建者、传参方、异常处理及生命周期管理;单例应由容器管理而非类内getInstance;策略须接口统一、外部注入;原型需实现__clone/__wakeup;观察者notify须try/catch防中断。

PHP 里直接照搬「设计模式完整代码示例」容易踩坑——多数示例脱离真实调用上下文,类之间硬耦合、依赖没注入、__construct 塞满逻辑,跑通了但没法测、没法换实现、一加新需求就改出 bug。
真正能落地的模式代码,得先想清楚:这个模式在解决什么具体问题?谁在 new 它?谁在传参?异常怎么抛?生命周期谁管?
单例模式别用 getInstance() 全局访问
常见错误是写一个静态 getInstance(),然后到处 DB::getInstance()->query()。这导致单元测试无法 mock,也锁死了连接配置(比如测试要用 SQLite,生产用 MySQL)。
正确做法是让容器或工厂负责单例生命周期,类本身保持无状态:
<?php class Database
{
private PDO $pdo;
<pre class="brush:php;toolbar:false;">public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function query(string $sql): array { /* ... */ }
}
由 DI 容器统一管理 Database 实例的复用,而不是类自己“保证唯一”。new Database($pdo) 本身是无害的,重复 new 只是浪费资源;真要控制实例数,交给 Container::get(Database::class) 做即可。
策略模式的关键在运行时选择,不是定义一堆 if-else
很多人把策略模式写成:if ($type === 'wechat') { new WechatPay(); } elseif ($type === 'alipay') { new AlipayPay(); }——这根本不是策略,只是条件分支。
策略模式的核心是:行为可互换、客户端不感知具体实现。必须满足三点:
- 所有策略实现同一个接口(如
PaymentStrategy) - 上下文类(如
OrderProcessor)只依赖该接口,不依赖具体类名 - 策略实例由外部注入或工厂返回,不是内部 new
示例中容易漏掉的是错误处理一致性:pay() 方法该抛 PaymentFailedException 还是返回布尔值?所有策略必须约定好,否则调用方要写 N 种判断逻辑。
__clone 和 __wakeup 在原型模式里不是可选项
用 clone $obj 实现原型模式时,如果对象含资源句柄(如 mysqli 连接)、闭包、或引用其他对象,直接 clone 会出错或共享状态。
必须显式定义 __clone() 来重置关键属性:
public function __clone()
{
$this->id = null; // 重置主键
$this->connection = null; // 断开数据库连接引用
$this->logger = clone $this->logger; // 深拷贝日志器(如果支持)
}
同理,如果原型对象被序列化后反序列化(unserialize),__wakeup() 也要做类似清理——否则反序列化出来的对象可能持有已关闭的资源句柄,后续调用直接 fatal error。
观察者模式里别让监听器抛未捕获异常
notify() 遍历监听器时,一个监听器 throw Exception 会导致后续监听器完全不执行。这不是理论风险,而是线上高频问题(比如短信服务挂了,导致邮件通知也发不出)。
解决方式很朴素:在循环内加 try/catch,记录错误但不停止流程:
foreach ($this->observers as $observer) {
try {
$observer->update($event);
} catch (Throwable $e) {
error_log('Observer failed: ' . $e->getMessage());
// 不 re-throw,继续下一个
}
}
更进一步,异步解耦(如投递到队列)比同步 notify 更健壮,但代价是事件最终一致性——这点必须和业务方对齐,不能默认“用了观察者就等于实时响应”。
真实项目里,模式的价值不在“用了哪个”,而在“去掉它是否立刻难维护”。最常被忽略的不是语法,是边界:谁创建、谁销毁、谁处理失败、谁保证顺序。这些不写进代码注释或交接文档,半年后谁都看不懂当初为什么这么写。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











