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

C++ 設計模式:裝飾模式深度解析與代碼實現

     編輯:關於C++

模式定義

裝飾模式:動態地給對象添加額外職責。相比生成子類,裝飾模式更靈活。屬於結構型模式。

核心痛點:繼承的侷限性

需為窗口控件添加滾動條、背景圖、邊框等功能。若用繼承:
ScrollWindow、BgWindow、ScrollBgWindow、BorderWindow...
類爆炸,且功能組合僵化(ScrollBgWindow 的滾動邏輯無法復用給 ListBox)。

裝飾模式結構

  • Component:抽象構件接口,定義核心操作 operation()。
  • ConcreteComponent:具體被裝飾對象。
  • Decorator:抽象裝飾類,繼承 Component 並聚合 Component 指針。
  • ConcreteDecoratorA/B:具體裝飾,實現具體功能增強。

關鍵設計:聚合 + 繼承 = 透明擴展

Decorator 既是 Component(繼承),又擁有 Component(聚合)。調用鏈:
Client → DecoratorA → DecoratorB → ConcreteComponent

代碼實現(兩種風格)

風格一:父類定義 addOperate 虛函數(模板方法風格)

class Component {
public:
    virtual ~Component() {}
    virtual void operate() { cout << "Component\n"; }
};

class Decorator : public Component {
protected:
    Component* comp;
    Decorator(Component* c) : comp(c) {}
    virtual void addBehavior() {} // 子類實現具體增強
public:
    void operate() override {
        addBehavior();      // 先做增強
        if (comp) comp->operate(); // 再委託被裝飾對象
    }
};

class DecoratorA : public Decorator {
    void addBehavior() override { cout << "DecoratorA + "; }
public:
    DecoratorA(Component* c) : Decorator(c) {}
};

class DecoratorB : public Decorator {
    void addBehavior() override { cout << "DecoratorB + "; }
public:
    DecoratorB(Component* c) : Decorator(c) {}
};

// 使用
Component* obj = new DecoratorA(new DecoratorB(new Component()));
obj->operate(); // 輸出: DecoratorA + DecoratorB + Component

風格二:子類完全控制 operate(更靈活,推薦)

class Decorator : public Component {
protected:
    Component* comp;
    Decorator(Component* c) : comp(c) {}
public:
    void operate() override {
        if (comp) comp->operate(); // 默認只委託
    }
};

class DecoratorA : public Decorator {
public:
    DecoratorA(Component* c) : Decorator(c) {}
    void operate() override {
        Decorator::operate(); // 先委託內層
        cout << "DecoratorA\n"; // 再做自己的事
    }
};

class DecoratorB : public Decorator {
public:
    DecoratorB(Component* c) : Decorator(c) {}
    void operate() override {
        cout << "DecoratorB\n";
        Decorator::operate();
    }
};

UML 類圖


Component <|-- ConcreteComponent
Component <|-- Decorator
Decorator o-- Component
Decorator <|-- ConcreteDecoratorA
Decorator <|-- ConcreteDecoratorB

優缺點總結

優點缺點
運行時動態組合功能邏輯比繼承複雜,調試難度大
避免類爆炸,符合開閉原則過度使用產生大量小對象,影響性能
單一職責:每個裝飾類只負責一項功能客戶端需知道具體裝飾順序
可嵌套多層裝飾難以移除中間某層裝飾

適用場景

  • 需要動態給對象添加/移除功能。
  • 無法使用繼承(類已 final、或繼承導致類爆炸)。
  • 功能之間獨立、可任意組合(如 IO 流:BufferedReader(new InputStreamReader(new FileInputStream(...))))。

總結

裝飾模式以聚合替代繼承,實現運行時動態擴展。核心結構:抽象裝飾類繼承組件接口並聚合組件指針。風格二(子類重寫 operate 完全控制調用順序)更靈活,推薦實戰使用。Java IO、C++ iostream、React HOC 都是裝飾模式的經典應用。

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