註冊表模式提供一個全局可訪問的容器,用於存儲和檢索應用程序中需要共享的對象或數據(如資料庫連接、配置對象、緩存客戶端、Service 實例等)。它本質上是一個「受控的全局變量」,避免了到處傳遞依賴或濫用 global 關鍵字。
set($key, $value) / get($key)class Registry
{
private static $instance = null;
private $containers = [];
// 私有構造函數,防止外部 new
private function __construct() {}
// 禁止克隆
private function __clone() {}
// 獲取單例實例
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
// 註冊對象/數據
public function set(string $key, $value): void
{
$this->containers[$key] = $value;
}
// 獲取對象/數據
public function get(string $key)
{
return $this->containers[$key] ?? null;
}
// 可選:檢查是否存在
public function has(string $key): bool
{
return isset($this->containers[$key]);
}
// 可選:移除
public function remove(string $key): void
{
unset($this->containers[$key]);
}
}
// 註冊核心服務
$registry = Registry::getInstance();
$registry->set('db', new PDO($dsn, $user, $pass));
$registry->set('cache', new RedisClient());
$registry->set('config', ['app_name' => 'MyApp', 'debug' => true]);
// 任意處獲取
$db = Registry::getInstance()->get('db');
$stmt = $db->query('SELECT * FROM users');
$config = Registry::getInstance()->get('config');
echo $config['app_name']; // MyApp
| ✅ 適合 | ❌ 不適合 |
|---|---|
| 資料庫連接、緩存客戶端、配置對象 | 頻繁變化的業務數據(用 Repository/Entity) |
| 第三方 SDK 實例(支付、短信、存儲) | 大量臨時變量(污染全局命名空間) |
| 框架核心服務容器的簡易替代 | 需要依賴注入、生命周期管理的複雜場景 |
在 Laravel、Symfony、Hyperf 等現代框架中,服務容器(Service Container / DI Container) 才是管理依賴的標準方式,它提供:
註冊表模式適合輕量級項目、舊代碼遷移、或作為理解 DI 容器的入門階梯。
註冊表模式用最簡單的代碼解決了「全局共享對象存取」的問題。掌握它,能幫你理解依賴管理的本質;超越它,則是擁抱現代框架的強大 DI 容器。選擇合適的工具,讓代碼既乾淨又有擴展性。