設計模式是軟體工程的「結構圖紙」,提供可重用、可讀、可靠的代碼組織方式。PHP 物件導向開發中,掌握核心模式能大幅提升架構品質。
<?php
class Singleton {
// 1. 靜態實例容器
private static $_instance = null;
// 2. 私有建構子,防止外部 new
private function __construct() {
// 初始化資源 (DB 連線、讀取配置等)
}
// 3. 私有克隆,防止 clone
private function __clone() {}
// 4. 私有反序列化,防止 unserialize
private function __wakeup() {}
// 5. 公共靜態取得實例方法
public static function getInstance() {
if (self::$_instance === null) {
self::$_instance = new self();
}
return self::$_instance;
}
// 業務方法
public function sayHi() {
echo "Hi boy!";
}
}
// 使用方式
$app = Singleton::getInstance();
$app->sayHi(); // Hi boy!
// 多次呼叫回傳同一實例
$app2 = Singleton::getInstance();
var_dump($app === $app2); // true
| 要素 | 實作 | 目的 |
|---|---|---|
| 私有建構子 | `private function __construct()` | 防止 `new Singleton()` |
| 靜態實例變數 | `private static $_instance` | 保存唯一實例 |
| 公共靜態取得方法 | `public static function getInstance()` | 全域存取點 |
| 私有 `__clone` | `private function __clone() {}` | 防止 `clone $obj` |
| 私有 `__wakeup` | `private function __wakeup() {}` | 防止 `unserialize()` 產生新實例 |
當有大量實作同一介面的類別,業務邏輯中散落 `new ClassA()`、`new ClassB()`,導致耦合度高、難以維護、擴充新類別需修改多處代碼。
<?php
// 1. 定義介面
interface ProductInterface {
public function showProductInfo();
}
// 2. 具體產品實作
class ProductA implements ProductInterface {
public function showProductInfo() { echo 'This is product A.'; }
}
class ProductB implements ProductInterface {
public function showProductInfo() { echo 'This is product B.'; }
}
// 3. 工廠類別
class ProductFactory {
public static function factory($type) {
$className = 'Product' . strtoupper($type);
if (class_exists($className)) {
return new $className();
}
throw new Exception("Product type '$type' not found.");
}
}
// 4. 客戶端使用
$x = ProductFactory::factory('A');
$x->showProductInfo(); // This is product A.
$o = ProductFactory::factory('B');
$o->showProductInfo(); // This is product B.
| 模式 | 特徵 | 適用 |
|---|---|---|
| 簡單工廠 | 單一類別靜態方法建立所有產品 | 產品種類少、建立邏輯簡單 |
| 工廠方法 | 抽象工廠類別 + 多個具體工廠子類別 | 每個產品建立邏輯複雜、需擴充 |
| 抽象工廠 | 建立相關/相依物件家族的介面 | 多個產品族 (如不同 DB 驅動全套) |