PHP 中的设计模式
设计模式是解决特定问题的通用模板,它们在软件工程中被广泛使用,以提高代码的可维护性、可扩展性和可重用性。PHP 作为一种面向对象的编程语言,可以使用多种设计模式。以下是一些常见的设计模式及其使用场景、历史来源和底层原理。
常见的设计模式
1. 单例模式 (Singleton Pattern)
使用场景:确保一个类只有一个实例,并提供一个全局访问点。历史来源:首次出现在 1995 年的《设计模式:可复用面向对象软件的基础》(Gang of Four, GoF)一书中。底层原理:
私有构造函数,防止外部实例化。静态私有成员变量存储唯一实例。提供静态方法返回该实例。
class Singleton {
private static $instance = null;
private function __construct() {
// 私有构造函数
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
}
2. 工厂模式 (Factory Pattern)
使用场景:定义一个用于创建对象的接口,但让子类决定实例化哪一个类。历史来源:GoF 设计模式之一。底层原理:
定义一个创建对象的接口。子类实现这个接口来创建具体的对象。
interface LoggerFactory {
public function createLogger();
}
class FileLoggerFactory implements LoggerFactory {
public function createLogger() {
return new FileLogger();
}
}
class DatabaseLoggerFactory implements LoggerFactory {
public function createLogger() {
return new DatabaseLogger();
}
}
3. 观察者模式 (Observer Pattern)
使用场景:当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。历史来源:GoF 设计模式之一。底层原理:
被观察者(Subject)维护一个观察者列表。观察者(Observer)注册到被观察者。当被观察者状态改变时,通知所有观察者。
interface Observer {
public function update($message);
}
class ConcreteObserver implements Observer {
public function update($message) {
echo "Received: " . $message . "\n";
}
}
class Subject {
private $observers = [];
public function attach(Observer $observer) {
$this->observers[] = $observer;
}
public function notify($message) {
foreach ($this->observers as $observer) {
$observer->update($message);
}
}
}
4. 策略模式 (Strategy Pattern)
使用场景:定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换。历史来源:GoF 设计模式之一。底层原理:
定义一个策略接口。实现多个具体策略类。上下文类使用策略接口,可以在运行时切换不同的策略。
interface PaymentStrategy {
public function pay($amount);
}
class CreditCardPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paid with credit card: $" . $amount . "\n";
}
}
class PayPalPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paid with PayPal: $" . $amount . "\n";
}
}
class ShoppingCart {
private $paymentStrategy;
public function setPaymentStrategy(PaymentStrategy $strategy) {
$this->paymentStrategy = $strategy;
}
public function checkout($amount) {
$this->paymentStrategy->pay($amount);
}
}
5. 装饰器模式 (Decorator Pattern)
使用场景:动态地给对象添加一些额外的功能,而不需要修改其结构。历史来源:GoF 设计模式之一。底层原理:
定义一个组件接口。具体组件实现该接口。装饰器类也实现该接口,并包含一个指向组件的引用。装饰器类可以在调用组件的方法前后添加额外的行为。
interface Coffee {
public function cost();
public function getDescription();
}
class SimpleCoffee implements Coffee {
public function cost() {
return 10;
}
public function getDescription() {
return "Simple Coffee";
}
}
abstract class CoffeeDecorator implements Coffee {
protected $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
public function cost() {
return $this->coffee->cost();
}
public function getDescription() {
return $this->coffee->getDescription();
}
}
class MilkDecorator extends CoffeeDecorator {
public function cost() {
return $this->coffee->cost() + 2;
}
public function getDescription() {
return $this->coffee->getDescription() . ", Milk";
}
}
6. 适配器模式 (Adapter Pattern)
使用场景:将一个类的接口转换成客户端所期望的另一个接口。历史来源:GoF 设计模式之一。底层原理:
定义一个目标接口。创建一个适配器类,实现目标接口,并持有一个对现有类的引用。适配器类通过调用现有类的方法来实现目标接口的方法。
interface Target {
public function request();
}
class Adaptee {
public function specificRequest() {
echo "Specific request from Adaptee\n";
}
}
class Adapter implements Target {
private $adaptee;
public function __construct(Adaptee $adaptee) {
$this->adaptee = $adaptee;
}
public function request() {
$this->adaptee->specificRequest();
}
}
7. 代理模式 (Proxy Pattern)
使用场景:为其他对象提供一个代理,以控制对这个对象的访问。历史来源:GoF 设计模式之一。底层原理:
定义一个与真实对象相同的接口。代理类持有对真实对象的引用,并在适当的时候调用真实对象的方法。
interface Image {
public function display();
}
class RealImage implements Image {
private $filename;
public function __construct($filename) {
$this->filename = $filename;
$this->loadFromDisk();
}
private function loadFromDisk() {
echo "Loading " . $this->filename . " from disk\n";
}
public function display() {
echo "Displaying " . $this->filename . "\n";
}
}
class ProxyImage implements Image {
private $realImage;
private $filename;
public function __construct($filename) {
$this->filename = $filename;
}
public function display() {
if ($this->realImage == null) {
$this->realImage = new RealImage($this->filename);
}
$this->realImage->display();
}
}
总结
设计模式:设计模式是一种解决特定问题的通用模板,提高了代码的可维护性、可扩展性和可重用性。使用场景:每种设计模式都有其特定的应用场景,例如单例模式用于确保唯一实例,工厂模式用于创建对象,观察者模式用于事件驱动等。历史来源:大多数设计模式来源于 1995 年出版的《设计模式:可复用面向对象软件的基础》一书。底层原理:每个设计模式都有其核心思想和实现机制,例如通过封装、继承、多态等面向对象特性来实现特定的功能。
理解这些设计模式及其应用场景和底层原理,可以帮助你更好地利用设计模式来构建高质量的 PHP 应用程序。