首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 設計模式實戰:裝飾器模式優雅擴展繪圖功能

     編輯:PHP 相關知識

PHP 設計模式實戰:裝飾器模式優雅擴展繪圖功能

裝飾器模式允許在不修改原類代碼、不使用繼承的情況下,動態為物件添加新行為。本文通過「畫板繪圖」實例,對比傳統繼承與裝飾器模式,展示如何實現繪圖功能的靈活組合擴展。

場景:畫板繪製矩形

基礎 Canvas 類支援初始化畫布、繪製矩形、輸出字符畫:

class Canvas {
    public $data;
    public function init($width = 20, $height = 10) { /* 初始化 * 陣列 */ }
    public function rect($a1, $a2, $b1, $b2) { /* 繪製矩形區域 */ }
    public function draw() { /* 輸出字符畫 */ }
}

調用:$canvas->init(40,20)->rect(4,15,9,30)->draw(); 輸出矩形字符畫。

問題:需求變更導致代碼僵化

若需增加「顏色」、「加粗」、「標題」等樣式,傳統做法:

  • 修改 draw() 硬編碼 HTML 標籤 → 違反開閉原則
  • 繼承子類 ColorCanvas、BoldCanvas → 組合爆炸,靈活性差

裝飾器模式重構

1. 定義裝飾器介面

interface DrawDecorator {
    public function beforeDraw();
    public function afterDraw();
}

2. 實現具體裝飾器(顏色)

class ColorDrawDecorator implements DrawDecorator {
    protected $color;
    public function __construct($color = 'red') { $this->color = $color; }
    public function beforeDraw() { echo "<div style='color:{$this->color}'>"; }
    public function afterDraw() { echo "</div>"; }
}

3. 重構 Canvas 支援裝飾器注入

class Canvas {
    public $data;
    protected $decorators = [];
    
    public function addDecorator(DrawDecorator $decorator) {
        $this->decorators[] = $decorator;
    }
    
    protected function beforeDraw() {
        foreach ($this->decorators as $d) $d->beforeDraw();
    }
    
    protected function afterDraw() {
        foreach (array_reverse($this->decorators) as $d) $d->afterDraw();
    }
    
    public function draw() {
        $this->beforeDraw();
        // 原有繪圖邏輯
        $this->afterDraw();
    }
    // init、rect 等方法保持不變...
}

4. 客戶端靈活組合

$canvas = new Canvas();
$canvas->addDecorator(new ColorDrawDecorator('green'));  // 注入綠色裝飾器
$canvas->init(40, 20);
$canvas->rect(4, 15, 9, 30);
$canvas->draw();  // 輸出綠色矩形

擴展性驗證

新增需求只需建立新裝飾器類,無需修改 Canvas:

  • BoldDrawDecorator → 加粗
  • ItalicDrawDecorator → 傾斜
  • TitleDrawDecorator → 添加標題

多裝飾器疊加:$canvas->addDecorator(new ColorDrawDecorator('red'))->addDecorator(new BoldDrawDecorator());

核心優勢總結

  1. 運行時動態組合:而非編譯時靜態繼承
  2. 單一職責:每個裝飾器只關注一項功能
  3. 開閉原則:對擴展開放,對修改關閉
  4. 避免子類爆炸:N 種功能組合只需 N 個裝飾器類

關聯模式

裝飾器本質類似「鉤子機制」,Drupal 的 Hook 系統、WordPress 的 Filter/Action 機制皆為此模式變體。亦可用 call_user_func_array 實現輕量級裝飾器調度。

掌握裝飾器模式,能讓你在面對頻繁變化的橫切關注點(日誌、緩存、權限、樣式)時,從容應對,寫出可維護、可擴展的優雅代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved