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

C++ 設計模式:組合模式深度解析——樹形結構的統一處理

     編輯:關於C++

模式定義

組合模式:將對象組合成樹形結構以表示「部分-整體」層次。使客戶端對單個對象和組合對象的使用具有一致性。屬於結構型模式。

核心場景:遞歸樹形結構

  • 文件系統:目錄包含子目錄/文件,目錄又包含子目錄/文件...
  • 公司組織:公司包含部門,部門包含子部門/員工。
  • GUI 控件:容器包含子控件,子控件可能是容器。

三大角色

  • Component:抽象構件,聲明公共接口 operation()、add()、remove()、getChild()。
  • Leaf:葉子構件,實現 operation(),add/remove/getChild 拋異常或空實現。
  • Composite:容器構件,維護子構件列表,實現 add/remove/getChild,operation() 遞歸調用子構件。

代碼實現

class Component {
public:
    virtual ~Component() {}
    virtual void operation() = 0;
    virtual void add(Component* c) { throw runtime_error("Not supported"); }
    virtual void remove(Component* c) { throw runtime_error("Not supported"); }
    virtual Component* getChild(size_t idx) { return nullptr; }
};

class Leaf : public Component {
public:
    void operation() override { cout << "Leaf\n"; }
};

class Composite : public Component {
    vector children;
public:
    ~Composite() { for (auto c : children) delete c; }
    void operation() override {
        cout << "Composite (children: " << children.size() << ")\n";
        for (auto c : children) c->operation();
    }
    void add(Component* c) override { children.push_back(c); }
    void remove(Component* c) override {
        auto it = find(children.begin(), children.end(), c);
        if (it != children.end()) children.erase(it);
    }
    Component* getChild(size_t idx) override {
        return (idx < children.size()) ? children[idx] : nullptr;
    }
};

// 使用
int main() {
    Component* root = new Composite();
    root->add(new Composite());
    root->add(new Leaf());
    root->getChild(0)->add(new Leaf());
    root->getChild(0)->add(new Leaf());
    root->operation();
    delete root;
}

關鍵設計決策:透明式 vs 安全式

風格Component 聲明優點缺點
透明式add/remove/getChild 在 Component 中聲明客戶端統一調用,無需區分葉子/容器葉子類被迫實現無意義方法(拋異常)
安全式add/remove/getChild 只在 Composite 中聲明類型安全,葉子不受污染客戶端需轉型調用,破壞一致性

本文代碼採用透明式(GoF 推薦),利用異常/空實現處理葉子不支持的操作。

UML 類圖


Component <|-- Leaf
Component <|-- Composite
Composite o-- Component (children)

優缺點

  • 優點:簡化客戶端代碼(統一接口)、易於添加新構件類型、天然適合遞歸結構。
  • 缺點:設計過於泛化(葉子也有 add)、難以限制容器中允許的子構件類型、運行時才發現調用錯誤。

適用場景

  1. 表示對象的「部分-整體」層次結構。
  2. 客戶端希望統一對待單個對象和組合對象。
  3. 樹形結構且操作可遞歸定義(如遍歷、序列化、權限計算)。

經典應用

  • Java Swing / C# WinForms / Qt:Container 繼承 Component。
  • 文件系統:Directory 和 File 實現共同接口。
  • 組織架構、菜單系統、XML/JSON 節點樹。

總結

組合模式將遞歸數據結構映射為遞歸類結構。核心:Component 定義統一接口,Leaf 實現基本行為,Composite 遞歸委託子構件。透明式雖讓葉子背負無用方法,但換來客戶端代碼極致簡潔,是經典權衡。

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