PHP 入门教程
PHP 设计模式简介
本教程共 65 篇 · 第 61 篇 · 更新于 2026-07-24 · 约 10 分钟阅读
PHPPHP8设计模式单例模式工厂模式观察者模式策略模式
61. PHP 设计模式简介
本节目标:了解常用设计模式的核心思想,能够在合适场景下选择并应用正确的模式。
设计模式是解决常见软件设计问题的经过验证的方案。它不是具体的代码,而是一种思想。掌握设计模式能让代码更易维护、更易扩展。
1. 单例模式(Singleton)
确保一个类只有一个实例,并提供一个全局访问点。常用于数据库连接、配置管理等场景。
<?php
class Database
{
private static ?self $instance = null;
private PDO $pdo;
private function __construct()
{
$this->pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '123456');
}
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getPdo(): PDO
{
return $this->pdo;
}
// 禁止克隆和反序列化
private function __clone() {}
public function __wakeup()
{
throw new Exception("Cannot unserialize singleton");
}
}
// 使用
$db = Database::getInstance();
$stmt = $db->getPdo()->query("SELECT * FROM users");
Note单例模式有其争议。全局状态会让测试变得困难,依赖注入容器(如 Laravel 的服务容器)是更好的替代方案。仅在确有必要时使用单例。
2. 工厂模式(Factory)
将对象的创建逻辑封装到工厂类中,调用者无需关心具体实例化过程。
<?php
interface Logger {
public function log(string $message): void;
}
class FileLogger implements Logger {
public function log(string $message): void {
file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
}
}
class DbLogger implements Logger {
public function log(string $message): void {
echo "[DB] {$message}\n";
}
}
class LoggerFactory {
public static function create(string $type): Logger {
return match ($type) {
'file' => new FileLogger(),
'db' => new DbLogger(),
default => throw new InvalidArgumentException('未知日志类型'),
};
}
}
// 使用
$logger = LoggerFactory::create('file');
$logger->log('系统启动');
Tip工厂模式让代码更易扩展。新增日志类型时,只需修改工厂,不影响调用方。
3. 观察者模式(Observer)
定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者自动收到通知。
<?php
interface Observer {
public function update(string $event): void;
}
class UserService {
private array $observers = [];
public function attach(Observer $observer): void {
$this->observers[] = $observer;
}
public function createUser(string $name): void {
echo "创建用户:{$name}\n";
$this->notify('user.created');
}
private function notify(string $event): void {
foreach ($this->observers as $observer) {
$observer->update($event);
}
}
}
class EmailNotifier implements Observer {
public function update(string $event): void {
if ($event === 'user.created') {
echo "发送欢迎邮件\n";
}
}
}
class LogNotifier implements Observer {
public function update(string $event): void {
echo "记录日志:{$event}\n";
}
}
// 使用
$service = new UserService();
$service->attach(new EmailNotifier());
$service->attach(new LogNotifier());
$service->createUser('张三');
4. 策略模式(Strategy)
定义一系列算法,将它们封装起来,并且使它们可以互相替换。
<?php
interface PaymentStrategy {
public function pay(float $amount): string;
}
class AlipayStrategy implements PaymentStrategy {
public function pay(float $amount): string {
return "支付宝支付 {$amount} 元";
}
}
class WechatStrategy implements PaymentStrategy {
public function pay(float $amount): string {
return "微信支付 {$amount} 元";
}
}
class PaymentContext {
public function __construct(private PaymentStrategy $strategy) {}
public function executePay(float $amount): string {
return $this->strategy->pay($amount);
}
public function setStrategy(PaymentStrategy $strategy): void {
$this->strategy = $strategy;
}
}
// 使用
$payment = new PaymentContext(new AlipayStrategy());
echo $payment->executePay(100); // 支付宝支付 100 元
$payment->setStrategy(new WechatStrategy());
echo $payment->executePay(100); // 微信支付 100 元
5. 模式使用建议
| 场景 | 推荐模式 |
|---|---|
| 全局唯一的数据库连接 | 单例模式 |
| 根据不同条件创建不同对象 | 工厂模式 |
| 事件触发后执行多个动作 | 观察者模式 |
| 多种算法/策略可互换 | 策略模式 |
Note不要为了用模式而用模式。简单的逻辑直接写即可,过度设计会增加复杂度。
小结
设计模式是前人总结的最佳实践。理解核心思想后,结合具体业务灵活运用,能让代码结构更清晰、更易于维护。
来源:参考了 php-the-right-way「Design Patterns」、refactoring.guru,改写后所得。