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

設計模式實作系列(八):Composite 組合模式 - 樹形結構統一單個與群組物件操作

     編輯:關於C++

模式意圖

將物件組合成樹形結構以表示「部分-整體」的層次結構。Composite 使得用戶對單個物件和組合物件的使用具有一致性。

UML 結構圖

Composite Pattern UML

核心解析

  • Component: 抽象基類,宣告 Operation() 及子物件管理介面 Add/Remove/GetChild(預設空實作)。
  • Leaf: 葉節點,無子物件,實作 Operation(),Add/Remove 拋出異常或忽略。
  • Composite: 容器節點,維護子物件列表(std::list<Component*>),Operation() 遞迴呼叫所有子物件。
  • 關鍵: 客戶端統一操作 Component*,無需區分葉節點或容器。

C++ 完整實作

1. Composite.h

#ifndef COMPOSITE_H
#define COMPOSITE_H

#include <list>

class Component {
public:
    Component() {}
    virtual ~Component() {}
    virtual void Operation() = 0;
    virtual void Add(Component* pChild) {}
    virtual void Remove(Component* pChild) {}
    virtual Component* GetChild(int nIndex) { return nullptr; }
};

class Leaf : public Component {
public:
    Leaf() {}
    virtual ~Leaf() {}
    virtual void Operation();
};

class Composite : public Component {
public:
    Composite() {}
    virtual ~Composite();
    virtual void Operation();
    virtual void Add(Component* pChild);
    virtual void Remove(Component* pChild);
    virtual Component* GetChild(int nIndex);
private:
    std::list<Component*> m_ListOfComponent;
};

#endif

2. Composite.cpp

#include "Composite.h"
#include <iostream>
#include <algorithm>

void Leaf::Operation() { std::cout << "Operation by leaf\n"; }

Composite::~Composite() {
    for (auto p : m_ListOfComponent) delete p;
    m_ListOfComponent.clear();
}
void Composite::Add(Component* pChild) { m_ListOfComponent.push_back(pChild); }
void Composite::Remove(Component* pChild) {
    auto it = std::find(m_ListOfComponent.begin(), m_ListOfComponent.end(), pChild);
    if (it != m_ListOfComponent.end()) m_ListOfComponent.erase(it);
}
Component* Composite::GetChild(int nIndex) {
    if (nIndex <= 0 || nIndex > (int)m_ListOfComponent.size()) return nullptr;
    auto it = m_ListOfComponent.begin();
    std::advance(it, nIndex - 1);
    return *it;
}
void Composite::Operation() {
    std::cout << "Operation by Composite\n";
    for (auto p : m_ListOfComponent) p->Operation(); // 遞迴
}

3. Main.cpp

#include "Composite.h"
#include <cstdlib>

int main() {
    Leaf* pLeaf1 = new Leaf();
    Leaf* pLeaf2 = new Leaf();
    Composite* pComposite = new Composite();
    pComposite->Add(pLeaf1);
    pComposite->Add(pLeaf2);
    pComposite->Operation();           // 整體操作
    pComposite->GetChild(2)->Operation(); // 存取單一葉節點
    delete pComposite;
    return 0;
}

安全與透明兩種設計

  • 透明模式(本實作): Component 宣告所有管理介面,Leaf 也擁有但拋出異常/忽略。客戶端完全統一。
  • 安全模式: 管理介面只宣告在 Composite,Leaf 不擁有。客戶端需區分型別(dynamic_cast),較安全但失去透明性。

適用場景

  • 檔案系統(檔案/目錄)、GUI 控制項樹(面板/按鈕)、組織架構(員工/部門)。
  • XML/HTML DOM 樹、編譯器 AST、數學運算式樹。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved