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

設計模式實戰:裝飾者模式 C++ 完整實現與開閉原則應用

     編輯:關於C++

裝飾者模式核心意圖

動態地**給對象添加職責**,無需修改原類代碼,且裝飾可任意組合、疊加。是繼承的靈活替代方案,完美體現「對修改關閉,對擴展開放」 (OCP)。

角色結構

  • Component (抽象組件):定義核心介面 (coreFunction1/2) 與擴展介面 (dosomething)。
  • ConcreteComponent (具體組件):被裝飾對象 (ConcreteComponentA/B/C),實現核心邏輯與基礎 dosomething。
  • Decorator (抽象裝飾者):繼承 Component,持有 Component* 指針,轉發調用。
  • ConcreteDecorator (具體裝飾者):OneDecorator/TwoDecorator/ThreeDecorator,在轉發前後添加具體裝飾邏輯。

完整代碼實現 (現代 C++ 風格)

1. 抽象組件介面


class Component {
public:
    virtual ~Component() = default;
    void coreFunction1() { cout << "核心方法1\n"; }
    void coreFunction2() { cout << "核心方法2\n"; }
    virtual void dosomething() = 0; // 擴展點
};

2. 具體組件


class ConcreteComponentA : public Component {
public:
    void dosomething() override { cout << "A類\n"; }
};
class ConcreteComponentB : public Component {
public:
    void dosomething() override { cout << "B類\n"; }
};
class ConcreteComponentC : public Component {
public:
    void dosomething() override { cout << "C類\n"; }
};

3. 抽象裝飾者 (關鍵:組合而非繼承核心邏輯)


class Decorator : public Component {
protected:
    Component* component; // 持有被裝飾對象
public:
    explicit Decorator(Component* comp) : component(comp) {}
    void dosomething() override { component->dosomething(); } // 默認透傳
};

4. 具體裝飾者 (疊加行為)


class OneDecorator : public Decorator {
public:
    using Decorator::Decorator;
    void dosomething() override {
        Decorator::dosomething(); // 調用被裝飾者
        cout << "添加了裝飾方法1\n";
    }
};
class TwoDecorator : public Decorator {
public:
    using Decorator::Decorator;
    void dosomething() override {
        Decorator::dosomething();
        cout << "添加了裝飾方法2\n";
    }
};
class ThreeDecorator : public Decorator {
public:
    using Decorator::Decorator;
    void dosomething() override {
        Decorator::dosomething();
        cout << "添加了裝飾方法3\n";
    }
};

5. 客戶端:任意組合裝飾


int main() {
    // 層層包裝:A 先加 3,再加 2,再加 1
    Component* obj1 = new OneDecorator(
                          new TwoDecorator(
                              new ThreeDecorator(
                                  new ConcreteComponentA)));
    obj1->dosomething();
    obj1->coreFunction1();
    obj1->coreFunction2();

    // 另一種組合:B 先加 1,再加 3
    Component* obj2 = new ThreeDecorator(
                          new OneDecorator(
                              new ConcreteComponentB));
    obj2->dosomething();
    obj2->coreFunction1();
    obj2->coreFunction2();

    // 記得釋放 (或用 unique_ptr 管理)
    delete obj1; // 需遞歸刪除,建議用智能指針
    delete obj2;
}

運行輸出

A類
添加了裝飾方法3
添加了裝飾方法2
添加了裝飾方法1
核心方法1
核心方法2

B類
添加了裝飾方法1
添加了裝飾方法3
核心方法1
核心方法2

現代 C++ 改良:智能指針管理生命週期


#include 
using ComponentPtr = std::unique_ptr;

class Decorator : public Component {
    ComponentPtr component; // 獨佔所有權
public:
    explicit Decorator(ComponentPtr comp) : component(std::move(comp)) {}
    void dosomething() override { component->dosomething(); }
};

// 使用
auto obj = std::make_unique(
               std::make_unique(
                   std::make_unique(
                       std::make_unique())));
// 自動釋放,無需手動 delete

裝飾者 vs 繼承 vs 策略模式

維度繼承裝飾者策略模式
靜態/動態編譯期靜態運行時動態組合運行時動態切換
組合方式單一繼承鏈層層包裝,任意排列整體替換算法對象
核心邏輯復用基類實現轉發被裝飾對象Context 委託 Strategy
適用場景is-a 關係穩定需疊加/移除職責算法族可互換

實戰應用場景

  • **I/O 流**:std::ostream 裝飾 std::ofstream、std::ostringstream (Java BufferedReader 同理)。
  • **GUI 組件**:邊框、滾動條、陰影疊加 (Java Swing JScrollPane 包裝 JTextArea)。
  • **中間件管道**:ASP.NET Core / Express.js 中間件鏈 (Logger → Auth → Router)。
  • **功能開關**:A/B 測試、灰度發布時動態添加/移除功能模塊。

總結

裝飾者模式以**組合替代繼承**,將單一職責拆分為獨立裝飾類,通過介面統一、指針持有、轉發調用實現行為疊加。C++ 實現關鍵點:虛析構、抽象裝飾類持有 Component 指針、具體裝飾類調用基類轉發再添加邏輯、客戶端構建裝飾鏈。配合 unique_ptr 實現 RAII 管理,代碼既優雅又安全。

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