PHP设计模式实战应用
设计模式是面向对象编程中经过验证的解决方案,它们不是可以直接复制的代码,而是解决特定问题的模板。在PHP开发中,合理使用设计模式可以让代码更灵活、更易维护、更易扩展。本文将介绍几种在PHP项目中常用的设计模式及其实战应用。
一、单例模式
确保一个类只有一个实例,常用于数据库连接、配置管理等场景:
class Database {
private static ?Database $instance = null;
private PDO $pdo;
private function __construct() {
$this->pdo = new PDO(
'mysql:host=localhost;dbname=myapp',
'root', '',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
}
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'); }
}
二、工厂模式
// 简单工厂
class NotificationFactory {
public static function create(string $type): Notification {
return match($type) {
'email' => new EmailNotification(),
'sms' => new SmsNotification(),
'push' => new PushNotification(),
default => throw new \InvalidArgumentException("不支持的类型: $type")
};
}
}
// 抽象工厂
interface StorageFactory {
public function createConnection(): StorageConnection;
public function createQueryBuilder(): QueryBuilder;
}
class MySQLFactory implements StorageFactory {
public function createConnection(): StorageConnection {
return new MySQLConnection();
}
public function createQueryBuilder(): QueryBuilder {
return new MySQLQueryBuilder();
}
}
三、策略模式
定义一系列算法,让它们可以互相替换。非常适合处理业务逻辑中的条件分支:
interface PricingStrategy {
public function calculate(float $price): float;
}
class RegularPricing implements PricingStrategy {
public function calculate(float $price): float { return $price; }
}
class DiscountPricing implements PricingStrategy {
public function __construct(private float $discount) {}
public function calculate(float $price): float {
return $price * (1 - $this->discount);
}
}
class VIPPricing implements PricingStrategy {
public function calculate(float $price): float {
return $price * 0.7; // VIP七折
}
}
class Order {
public function __construct(private PricingStrategy $strategy) {}
public function getTotal(float $price): float {
return $this->strategy->calculate($price);
}
}
四、观察者模式
interface EventListener {
public function handle(Event $event): void;
}
class EventDispatcher {
private array $listeners = [];
public function listen(string $event, EventListener $listener): void {
$this->listeners[$event][] = $listener;
}
public function dispatch(Event $event): void {
$listeners = $this->listeners[get_class($event)] ?? [];
foreach ($listeners as $listener) {
$listener->handle($event);
}
}
}
// 使用
class UserRegisteredEvent extends Event {
public function __construct(public User $user) {}
}
$dispatcher->listen(UserRegisteredEvent::class, new SendWelcomeEmail());
$dispatcher->listen(UserRegisteredEvent::class, new CreateDefaultProfile());
$dispatcher->dispatch(new UserRegisteredEvent($user));
五、装饰器模式
interface TextFormatter {
public function format(string $text): string;
}
class PlainText implements TextFormatter {
public function format(string $text): string { return $text; }
}
class BoldDecorator implements TextFormatter {
public function __construct(private TextFormatter $formatter) {}
public function format(string $text): string {
return '' . $this->formatter->format($text) . '';
}
}
class ItalicDecorator implements TextFormatter {
public function __construct(private TextFormatter $formatter) {}
public function format(string $text): string {
return '' . $this->formatter->format($text) . '';
}
}
// 组合使用
$text = new ItalicDecorator(new BoldDecorator(new PlainText()));
echo $text->format('Hello'); // Hello
设计模式不是银弹,不要为了使用而使用。关键在于理解每种模式解决的问题,在合适的场景下自然地运用它们。建议从项目中常见的痛点出发,看看哪种模式能优雅地解决你的问题。