本文透過一個「使用者投訴舉報系統」實例,示範 8 種經典設計模式在實際業務中的組合應用,涵蓋建構型、結構型、行為型三大類,展示如何透過模式解耦業務邏輯、提升擴充性。
| 業務需求 | 應用模式 | 角色 |
|---|---|---|
| 資料庫連線唯一實例 | 單例模式 | MysqlSingle |
| 統一建立資料庫連線介面 | 工廠模式 | MysqlFactory |
| 依用戶身份切換顯示風格 | 觀察者模式 | Observer / StyleA,B |
| 投訴管道(Email/SMS)與等級(Normal/Danger)解耦 | 橋接模式 | Bridge / BridgeEmail,Sms / Normal,Danger |
| 投訴資料支援多種序列化格式 | 適配器模式 | Serialize / JsonAdapter |
| 投訴內容自動附加系統時間 | 裝飾器模式 | Base / Decorator |
| 分級處理流程(一級→二級→三級) | 責任鏈模式 | Level1,2,3 |
| 依發文長度給予不同經驗值策略 | 策略模式 | (程式碼中註解預留) |
interface DB { public function conn(); }
class MysqlSingle implements DB {
private static $instance = null;
private function __construct() { echo "Mysql單例建立成功
"; }
private function __clone() {}
public static function getInstance() {
if (!self::$instance instanceof self) self::$instance = new self();
return self::$instance;
}
public function conn() { echo "Mysql連線成功
"; }
}
interface Factory { public function createDB(); }
class MysqlFactory implements Factory {
public function createDB() {
echo "Mysql工廠建立成功
";
return MysqlSingle::getInstance();
}
}
class Observer implements SplSubject {
private $observers;
public $style;
public function __construct($style) {
$this->style = $style;
$this->observers = new SplObjectStorage();
}
public function attach(SplObserver $o) { $this->observers->attach($o); }
public function detach(SplObserver $o) { $this->observers->detach($o); }
public function notify() {
foreach ($this->observers as $o) $o->update($this);
}
public function show() { $this->notify(); }
}
class StyleA implements SplObserver {
public function update(SplSubject $s) { echo $s->style . " 模組A
"; }
}
class StyleB implements SplObserver {
public function update(SplSubject $s) { echo $s->style . " 模組B
"; }
}
abstract class Bridge {
protected $impl;
public function __construct($impl) { $this->impl = $impl; }
abstract public function msg();
public function show() { $this->msg(); $this->impl->msg(); }
}
class BridgeEmail extends Bridge { public function msg() { echo "Email>>"; } }
class BridgeSms extends Bridge { public function msg() { echo "Sms>>"; } }
class Normal { public function msg() { echo "Normal
"; } }
class Danger { public function msg() { echo "Danger
"; } }
// 使用:new BridgeEmail(new Danger())->show(); // Email>>Danger
class Serialize {
public $content;
public function __construct($content) { $this->content = serialize($content); }
public function show() { return "序列化格式:
" . $this->content; }
}
class JsonAdapter extends Serialize {
public function __construct($content) {
parent::__construct($content);
$this->content = json_encode(unserialize($this->content), JSON_UNESCAPED_UNICODE);
}
public function show() { return "JSON格式:
" . $this->content; }
}
class Base { protected $content; public function __construct($c) { $this->content = $c; } public function get() { return $this->content; } }
class Decorator {
private $base;
public function __construct(Base $b) { $this->base = $b; }
public function show() { return $this->base->get() . ">>系統時間:" . date('Y-m-d H:i:s'); }
}
class Level1 { protected $level=1; protected $next='Level2';
public function deal($l) { if($l<=$this->level){echo "處理級別:1
";return;} (new $this->next)->deal($l); } }
class Level2 { protected $level=2; protected $next='Level3';
public function deal($l) { if($l<=$this->level){echo "處理級別:2
";return;} (new $this->next)->deal($l); } }
class Level3 { protected $level=3;
public function deal($l) { echo "處理級別:3
"; } }
if ($_POST) {
// 1. 工廠+單例建立連線
$db = (new MysqlFactory())->createDB(); $db->conn();
// 2. 觀察者通知風格模組
$obs = new Observer($_POST['username']);
$obs->attach(new StyleA()); $obs->attach(new StyleB());
$obs->show(); $obs->detach(new StyleB()); $obs->show();
// 3. 橋接組合管道與等級
$bridge = "Bridge{$_POST['typeN']}";
$level = $_POST['typeM'];
(new $bridge(new $level()))->show();
// 4. 適配器輸出多格式
$ser = new Serialize($_POST); echo $ser->show();
$json = new JsonAdapter($_POST); echo $json->show();
// 5. 裝飾器附加時間
echo (new Decorator(new Base($_POST['content'])))->show();
// 6. 責任鏈分級處理
(new Level1())->deal((int)$_POST['level']);
exit;
}
此範例展示設計模式非孤立存在,而是透過組合解決真實業務複雜度。讀者可嘗試擴充:加入「策略模式」計算經驗值、「模板方法」統一投訴處理骨架、「狀態模式」管理投訴狀態流轉。