php设计模式是解决特定问题的成熟方案,分为创建型、结构型、行为型三类;单例用于全局唯一对象,策略用于算法替换,适配器用于接口兼容,核心在于识别问题而非背诵概念。

PHP 设计模式不是靠背概念学会的,而是靠在真实问题里反复识别、替换、验证才真正掌握的。没写过三次以上单例类,就别谈理解“为什么不能 new”;没被策略模式救过两次 if-else 嵌套地狱,就很难体会接口抽象的价值。
先搞清你正在解决哪类问题,再匹配模式
设计模式本质是「问题分类器」,不是代码模板库。遇到以下场景时,对应模式才自然浮现:
- 需要全局唯一对象(如数据库连接、日志实例)→ 看
Singleton,重点检查是否真需“全局”,还是该用依赖注入 - 新增支付方式就要改一堆
switch或if→ 直接上Strategy,把不同支付逻辑拆成独立类,用统一接口调用 - 旧系统要对接新 API,但返回结构、错误码、认证方式全不兼容 →
Adapter是最轻量解法,不碰原逻辑,只包一层转换 - 表单渲染既要支持文本输入、下拉选择,又要组合成完整表单并统一输出 →
Composite+Renderable接口比硬拼 HTML 字符串靠谱得多
从 Laravel 源码里抄最实用的实现
别从《23 种模式详解》开始学。Laravel 的 ServiceContainer 就是工厂 + 单例 + 绑定解析的混合体;它的事件系统是 Observer 的工业级落地;缓存驱动切换用的是 Strategy。直接看:
-
vendor/laravel/framework/src/Illuminate/Container/Container.php:看bind()和make()怎么绕过new -
vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:观察者注册和触发怎么解耦监听器 -
vendor/laravel/framework/src/Illuminate/Cache/Repository.php:getDriver()方法背后就是策略分发
照着改两遍,比读十篇理论强。
警惕单例滥用——它是最常被误用的模式
很多初学者把 getInstance() 当万能钥匙,结果导致:
- 测试困难:
Singleton强制全局状态,无法 mock 或重置 - 隐藏依赖:类内部直接调用
DbConn::getInstance(),外部完全看不出它依赖什么 - 并发风险:PHP-FPM 下多个请求可能同时触发初始化,老式双检锁(
flock)容易漏掉边界
替代方案更推荐:
- 依赖注入容器管理生命周期(Laravel 的
app()->make()) - 构造函数传入已实例化的对象(显式依赖,易测易换)
- 静态工厂方法(
DbConn::createWithConfig($cfg)),比单例更可控
写第一个策略类前,先定义好接口契约
策略模式失效,90% 是因为没先想清楚接口。比如支付策略,不要定义 pay() 一个方法,而要明确:
-
validate(): bool—— 参数校验由策略自己负责 -
charge(array $data): array—— 返回标准结构:['success' => true, 'order_id' => 'xxx'] -
refund(string $order_id): bool—— 统一退款入口
接口一旦定死,后续加 WechatPay、Alipay、MockPay 就只是实现,不用动调用方任何一行代码。
if 分支、一个配置开关、一个可选参数,往往比引入整个模式更干净。模式是止痛药,不是维生素。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











