簡介
在這篇文章中將深入探討 Singleton Pattern(單例模式)在 PHP 中的實作和應用。我們會從基礎概念開始,然後透過一個以咖啡為主題的實際範例來說明如何使用 Singleton Pattern。文章的目的是讓讀者不僅了解 Singleton Pattern 的理論,還能掌握其實際應用。
什麼是 Singleton Pattern
Singleton Pattern 是一種設計模式,用於確保一個類別只有一個實例,並提供一個全局點來訪問它。
這是一個基本的 Singleton Pattern 的類別圖:
想像你走進一家咖啡店,這家咖啡店只有一台咖啡機。不論有多少人來買咖啡,都必須使用這台唯一的咖啡機。這台咖啡機就像是一個 Singleton,所有人都使用同一個實例。
什麼狀況適合使用 Singleton Pattern
在許多情境下,我們需要確保某個類別只有一個實例。例如,如果你有一個用於管理資料庫連接的類別,則通常只需要一個資料庫連接,而不是每次需要時都創建一個新的連接。這樣可以節省資源,提高效能。Singleton Pattern 就是為這種需求而生的。
範例教學
這個範例會以咖啡為主題來說明如何使用 Singleton Pattern。
原始範例,未使用 Singleton
這裡先創建一個 CoffeeMaker
類別,但不使用 Singleton Pattern。
<?php
class CoffeeMaker {
public function brew() {
echo "Brewing coffee...\n";
}
}
// 創建多個 CoffeeMaker 實例
$coffeeMaker1 = new CoffeeMaker();
$coffeeMaker2 = new CoffeeMaker();
$coffeeMaker1->brew();
$coffeeMaker2->brew();
?>
缺點
- 資源浪費:每次都會創建一個新的
CoffeeMaker
實例。 - 無法控制:無法確保只有一個
CoffeeMaker
實例。
改善範例,使用 Singleton
接下來,我們將使用 Singleton Pattern 來改進 CoffeeMaker
類別。
<?php
class CoffeeMaker {
private static $instance;
private function __construct() {
// 私有建構函數以防止外部創建實例
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new CoffeeMaker();
}
return self::$instance;
}
public function brew() {
echo "Brewing coffee...\n";
}
}
// 使用 Singleton 實例
$coffeeMaker1 = CoffeeMaker::getInstance();
$coffeeMaker2 = CoffeeMaker::getInstance();
$coffeeMaker1->brew();
$coffeeMaker2->brew();
?>
優點
- 資源節省:確保只有一個
CoffeeMaker
實例。 - 全局訪問:可以從任何地方訪問這個單一實例。
更多延伸範例
在這個延伸範例中,將添加一個 clean()
方法來清潔咖啡機。
<?php
class CoffeeMaker {
// ... (其他程式碼不變)
public function clean() {
echo "Cleaning the coffee machine...\n";
}
}
// 使用 Singleton 實例
$coffeeMaker = CoffeeMaker::getInstance();
$coffeeMaker->brew();
$coffeeMaker->clean();
?>
這樣,我們就可以輕鬆的只清潔一台咖啡機,而不用清潔一大堆咖啡機。
其他類似的 Design Pattern
除了 Singleton Pattern,還有其他一些設計模式也可以用於管理資源和實例,例如 Factory Pattern 和 Builder Pattern。這些模式各有其用途和優缺點。Factory Pattern 適用於需要創建多種類型的對象時,而 Builder Pattern 則適用於需要逐步構建對象的情況。
Design Pattern | 主要用途 | 優點 | 缺點 |
---|---|---|---|
Singleton | 管理單一實例 | 資源節省 | 可能造成全局狀態 |
Factory | 創建多種對象 | 靈活性高 | 複雜性增加 |
Builder | 逐步構建對象 | 易於維護 | 需要更多的類別和方法 |