常用设计模式
设计模式是解决特定问题的最佳实践,本文介绍 PHP 中常用的设计模式。
单例模式(Singleton)
确保一个类只有一个实例:
php
class Database {
private static $instance = null;
private $connection;
private function __construct() {
$this->connection = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getConnection() {
return $this->connection;
}
// 防止克隆和反序列化
private function __clone() {}
private function __wakeup() {}
}
// 使用
$db = Database::getInstance()->getConnection();工厂模式(Factory)
创建对象而不暴露创建逻辑:
php
interface PaymentInterface {
public function pay($amount);
}
class Alipay implements PaymentInterface {
public function pay($amount) {
echo "支付宝支付: ¥$amount";
}
}
class WechatPay implements PaymentInterface {
public function pay($amount) {
echo "微信支付: ¥$amount";
}
}
class PaymentFactory {
public static function create($type) {
switch ($type) {
case 'alipay': return new Alipay();
case 'wechat': return new WechatPay();
default: throw new Exception('不支持的方式');
}
}
}
// 使用
$payment = PaymentFactory::create('alipay');
$payment->pay(100);观察者模式(Observer)
事件订阅通知机制:
php
interface Observer {
public function update($event, $data);
}
class EventDispatcher {
private $observers = [];
public function attach($event, Observer $observer) {
$this->observers[$event][] = $observer;
}
public function detach($event, Observer $observer) {
if (isset($this->observers[$event])) {
$key = array_search($observer, $this->observers[$event]);
if ($key !== false) {
unset($this->observers[$event][$key]);
}
}
}
public function notify($event, $data = null) {
if (isset($this->observers[$event])) {
foreach ($this->observers[$event] as $observer) {
$observer->update($event, $data);
}
}
}
}
// 具体观察者
class EmailNotifier implements Observer {
public function update($event, $data) {
echo "发送邮件通知: $event\n";
}
}
class SmsNotifier implements Observer {
public function update($event, $data) {
echo "发送短信通知: $event\n";
}
}
// 使用
$dispatcher = new EventDispatcher();
$dispatcher->attach('user.register', new EmailNotifier());
$dispatcher->attach('user.register', new SmsNotifier());
$dispatcher->notify('user.register', ['user_id' => 1]);策略模式(Strategy)
定义算法族,让它们可以互相替换:
php
interface SortStrategy {
public function sort(array $data): array;
}
class BubbleSort implements SortStrategy {
public function sort(array $data): array {
// 冒泡排序实现
return $data;
}
}
class QuickSort implements SortStrategy {
public function sort(array $data): array {
// 快速排序实现
return $data;
}
}
class Sorter {
private $strategy;
public function setStrategy(SortStrategy $strategy) {
$this->strategy = $strategy;
}
public function sort(array $data): array {
return $this->strategy->sort($data);
}
}
// 使用
$sorter = new Sorter();
$sorter->setStrategy(new QuickSort());
$sorted = $sorter->sort([3, 1, 4, 1, 5]);装饰器模式(Decorator)
动态添加功能:
php
interface Coffee {
public function cost(): float;
public function description(): string;
}
class SimpleCoffee implements Coffee {
public function cost(): float { return 10; }
public function description(): string { return '简单咖啡'; }
}
abstract class CoffeeDecorator implements Coffee {
protected $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
}
class Milk extends CoffeeDecorator {
public function cost(): float {
return $this->coffee->cost() + 2;
}
public function description(): string {
return $this->coffee->description() . ', 牛奶';
}
}
class Sugar extends CoffeeDecorator {
public function cost(): float {
return $this->coffee->cost() + 1;
}
public function description(): string {
return $this->coffee->description() . ', 糖';
}
}
// 使用
$coffee = new SimpleCoffee();
$coffee = new Milk($coffee);
$coffee = new Sugar($coffee);
echo $coffee->description() . ' = ¥' . $coffee->cost();注意事项
- 不要过度设计,简单问题用简单方案
- 设计模式是工具,不是教条
- 理解模式的意图比记住实现更重要