裝飾模式:動態地給對象添加額外職責。相比生成子類,裝飾模式更靈活。屬於結構型模式。
需為窗口控件添加滾動條、背景圖、邊框等功能。若用繼承:
ScrollWindow、BgWindow、ScrollBgWindow、BorderWindow...
類爆炸,且功能組合僵化(ScrollBgWindow 的滾動邏輯無法復用給 ListBox)。
operation()。Decorator 既是 Component(繼承),又擁有 Component(聚合)。調用鏈:
Client → DecoratorA → DecoratorB → ConcreteComponent
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
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();
}
};
Component <|-- ConcreteComponent
Component <|-- Decorator
Decorator o-- Component
Decorator <|-- ConcreteDecoratorA
Decorator <|-- ConcreteDecoratorB
| 優點 | 缺點 |
|---|---|
| 運行時動態組合功能 | 邏輯比繼承複雜,調試難度大 |
| 避免類爆炸,符合開閉原則 | 過度使用產生大量小對象,影響性能 |
| 單一職責:每個裝飾類只負責一項功能 | 客戶端需知道具體裝飾順序 |
| 可嵌套多層裝飾 | 難以移除中間某層裝飾 |
BufferedReader(new InputStreamReader(new FileInputStream(...))))。裝飾模式以聚合替代繼承,實現運行時動態擴展。核心結構:抽象裝飾類繼承組件接口並聚合組件指針。風格二(子類重寫 operate 完全控制調用順序)更靈活,推薦實戰使用。Java IO、C++ iostream、React HOC 都是裝飾模式的經典應用。