首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP三大經典設計模式實作:單例、工廠、觀察者模式完整指南

     編輯:PHP 綜合知識

設計模式是軟體開發的通用解決方案。PHP開發中最常用的三大模式——單例、工廠、觀察者——分別解決資源唯一存取、物件建立解耦、事件驅動通訊三大核心需求。本文提供完整可執行實作代碼。

單例模式 - 確保全域唯一實例

適用場景:資料庫連線、配置管理、日誌記錄器等資源密集型服務。

三大要素:

  1. 私有建構子(private __construct())防止外部實例化
  2. 私有靜態屬性保存唯一實例
  3. 公開靜態方法(getInstance())提供存取點

PHP特有防禦:私有 __clone() 防止複製。

class Database {
    private static $instance;
    
    private function __construct() { /* 連線邏輯 */ }
    private function __clone() { /* 防止克隆 */ }
    
    public static function getInstance() {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$a = Database::getInstance();
$b = Database::getInstance();
var_dump($a === $b); // true - 同一實例

工廠模式 - 封裝物件建立邏輯

核心思想:根據輸入參數或配置,回傳對應介面的實作物件,呼叫端無需知道具體類別。

interface Shape {
    public function getArea();
    public function getCircumference();
}

class Rectangle implements Shape {
    private $width, $height;
    public function __construct($w, $h) { $this->width=$w; $this->height=$h; }
    public function getArea() { return $this->width * $this->height; }
    public function getCircumference() { return 2*($this->width + $this->height); }
}

class Circle implements Shape {
    private $radius;
    public function __construct($r) { $this->radius=$r; }
    public function getArea() { return M_PI * pow($this->radius, 2); }
    public function getCircumference() { return 2 * M_PI * $this->radius; }
}

class ShapeFactory {
    public static function create() {
        $args = func_get_args();
        switch (count($args)) {
            case 1: return new Circle($args[0]);
            case 2: return new Rectangle($args[0], $args[1]);
            default: throw new InvalidArgumentException('參數錯誤');
        }
    }
}

$rect = ShapeFactory::create(5, 5);  // Rectangle
$circle = ShapeFactory::create(4);   // Circle

觀察者模式 - 解耦事件發布與訂閱

核心角色:

  • Subject (被觀察者):維護觀察者清單,狀態變更時通知
  • Observer (觀察者):實作 update() 回應事件
interface Observer {
    public function onListen($sender, $args);
    public function getObserverName();
}

interface Observable {
    public function addObserver(Observer $o);
    public function removeObserver($name);
}

abstract class BaseObserver implements Observer {
    protected $observer_name;
    public function getObserverName() { return $this->observer_name; }
}

abstract class BaseObservable implements Observable {
    protected $observers = [];
    public function addObserver(Observer $o) { $this->observers[] = $o; }
    public function removeObserver($name) {
        foreach ($this->observers as $i => $o) {
            if ($o->getObserverName() === $name) {
                array_splice($this->observers, $i, 1);
                break;
            }
        }
    }
}

class EventSource extends BaseObservable {
    public function trigger($event) {
        foreach ($this->observers as $o) {
            $o->onListen($this, $event);
        }
    }
}

class Logger extends BaseObserver {
    protected $observer_name = 'Logger';
    public function onListen($sender, $args) {
        echo "[Log] Event: $args\n";
    }
}

class Notifier extends BaseObserver {
    protected $observer_name = 'Notifier';
    public function onListen($sender, $args) {
        echo "[Notify] Pushed: $args\n";
    }
}

// 使用
$source = new EventSource();
$source->addObserver(new Logger());
$source->addObserver(new Notifier());
$source->trigger('UserLogin'); // 兩個觀察者皆收到通知

模式選用指南

模式解決問題關鍵詞
單例全域唯一存取、資源共享getInstance、private constructor
工廠物件建立邏輯集中、解耦具體類別介面、多型、參數驅動
觀察者事件驅動、鬆耦合通訊訂閱/發布、事件循環
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved