什么是设计模式,为什么在 PHP 中需要它们?
设计模式(design patterns)是软件开发中常见问题的经过验证的解决方案。它们不是现成的代码,而是可以针对特定情况进行调整的模板。对于 PHP 开发者来说,了解设计模式有助于编写更灵活、更易维护和更具扩展性的代码。
在本文中,我们将分析 GoF(Gang of Four)目录中的四种基本设计模式,这些模式在 PHP 实际项目中最常用。每种模式都将附带实际示例和说明。
1. 单例模式(Singleton)
单例模式确保一个类只有一个实例,并提供一个全局访问点。这对于管理数据库连接、日志记录器或缓存非常有用。
何时使用?
- 只需要一个对象(例如,数据库连接)。
- 对象在整个应用程序中使用,且不允许创建重复项。
实现示例:
<?phpclass DatabaseConnection{ private static ?self $instance = null; private PDO $pdo;
private function __construct() { $this->pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); }
public static function getInstance(): self { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; }
public function getConnection(): PDO { return $this->pdo; }
// 禁止克隆和反序列化 private function __clone() {} public function __wakeup() { throw new \\Exception("Cannot unserialize singleton"); }}
// 使用方式:$db = DatabaseConnection::getInstance();$pdo = $db->getConnection();?>重要提示:单例模式常因违反单一职责原则和增加测试难度而受到批评。请有意识地使用它,并且只在确实需要的地方使用。
2. 工厂方法模式(Factory Method)
工厂方法模式定义了一个创建对象的接口,但允许子类更改所创建对象的类型。这允许将对象创建逻辑委托给子类。
何时使用?
- 事先不知道需要创建哪个具体对象。
- 希望向客户端隐藏复杂的对象创建逻辑。
实现示例:
<?php// 所有通知类型的接口interface Notification{ public function send(string $message): void;}
// 具体实现class EmailNotification implements Notification{ public function send(string $message): void { echo "发送邮件: {$message}"; }}
class SMSNotification implements Notification{ public function send(string $message): void { echo "发送短信: {$message}"; }}
// 抽象创建者abstract class NotificationFactory{ abstract public function createNotification(): Notification;
public function notify(string $message): void { $notification = $this->createNotification(); $notification->send($message); }}
// 具体工厂class EmailFactory extends NotificationFactory{ public function createNotification(): Notification { return new EmailNotification(); }}
class SMSFactory extends NotificationFactory{ public function createNotification(): Notification { return new SMSNotification(); }}
// 使用方式:$factory = new EmailFactory();$factory->notify("您的订单已确认!");
$factory = new SMSFactory();$factory->notify("验证码: 1234");