註冊樹模式(Registry Pattern)又稱註冊器模式,核心思想是:**提供一個全域可存取的容器(註冊樹),將各類物件實例「掛」在上面,需要時直接從樹上「摘」取**。
這就像圖書館的索引櫃:書籍(物件)歸位上架(註冊),讀者(呼叫端)查閱索引(別名)即可借閱(獲取),無需知道書籍具體放在哪個書架(建立細節)。
get($alias) 介面。get() 時才觸發實際建立。set()、get()、unset()、clear() 完整週期管理。<?php
class Register {
protected static $objects = [];
// 註冊物件(別名 => 實例)
public static function set($alias, $object) {
self::$objects[$alias] = $object;
}
// 獲取物件
public static function get($alias) {
return self::$objects[$alias] ?? null;
}
// 移除物件
public static function unset($alias) {
unset(self::$objects[$alias]);
}
// 判斷是否存在
public static function has($alias) {
return isset(self::$objects[$alias]);
}
// 清空所有(測試或重置時有用)
public static function clear() {
self::$objects = [];
}
}
<?php
// 1. 單例:資料庫連線
class Database {
private static $instance;
private $pdo;
private function __construct() {
$this->pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
}
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
public function getPdo() { return $this->pdo; }
}
// 2. 工廠:根據配置建立不同服務
class ServiceFactory {
public static function create($serviceName) {
switch ($serviceName) {
case 'db': return Database::getInstance();
case 'cache': return new RedisCache(); // 假設存在
case 'logger': return new FileLogger('/var/log/app.log');
default: throw new Exception("Unknown service: $serviceName");
}
}
}
// 3. 註冊樹:統一掛載
Register::set('db', ServiceFactory::create('db'));
Register::set('cache', ServiceFactory::create('cache'));
Register::set('logger', ServiceFactory::create('logger'));
// 4. 業務代碼中直接使用
$db = Register::get('db');
$cache = Register::get('cache');
$logger = Register::get('logger');
註冊樹是現代 PHP 框架(Laravel、Symfony)服務容器的**核心雛形**。進階容器會增加:
bind($alias, $closure) 支援延遲建立singleton($alias, $closure) 自動快取@var 註解,IDE 才能提供提示。Register::clear(),避免狀態污染。註冊樹模式看似簡單,卻是構建現代化 PHP 應用架構的基石。掌握它,你就理解了服務容器、依賴注入、控制反轉的核心運作機制。
系列文章: