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

組合模式詳解:樹形結構統一處理單個對象與組合對象

     編輯:C++ 入門

模式定義

組合模式將對象組合成樹形結構以表示「部分-整體」層次關係,使得客戶端代碼對單個對象(葉子)和組合對象(容器)的使用具有一致性。

適用場景

  • 需要表示對象的部分-整體層次結構(如文件系統、GUI 控件樹、菜單系統)
  • 希望客戶端忽略單個對象與組合對象的差異,統一調用接口

核心角色

  • Component(抽象構件):定義葉子與容器的公共接口,可選實現默認行為
  • Leaf(葉子構件):無子節點,實現具體業務邏輯
  • Composite(容器構件):包含子構件集合,實現 add/remove/getChild,遞歸調用子節點操作
  • Client(客戶端):通過 Component 接口操作樹結構

類圖

組合模式類圖

Java 代碼實現(菜單系統示例)


// 抽象構件
abstract class MenuComponent {
    public void add(MenuComponent c) { throw new UnsupportedOperationException(); }
    public void remove(MenuComponent c) { throw new UnsupportedOperationException(); }
    public MenuComponent getChild(int i) { throw new UnsupportedOperationException(); }
    public String getName() { throw new UnsupportedOperationException(); }
    public String getDescription() { throw new UnsupportedOperationException(); }
    public double getPrice() { throw new UnsupportedOperationException(); }
    public boolean isVegetarian() { throw new UnsupportedOperationException(); }
    public abstract void print();
}

// 葉子:菜單項
class MenuItem extends MenuComponent {
    private String name, description; private boolean vegetarian; private double price;
    public MenuItem(String n, String d, boolean v, double p) { ... }
    public String getName() { return name; }
    public String getDescription() { return description; }
    public double getPrice() { return price; }
    public boolean isVegetarian() { return vegetarian; }
    public void print() {
        System.out.print(" " + getName());
        if (isVegetarian()) System.out.print("(v)");
        System.out.println(", " + getPrice() + " -- " + getDescription());
    }
}

// 容器:菜單
class Menu extends MenuComponent {
    private List<MenuComponent> items = new ArrayList<>();
    private String name, description;
    public Menu(String n, String d) { name=n; description=d; }
    public void add(MenuComponent c) { items.add(c); }
    public void remove(MenuComponent c) { items.remove(c); }
    public MenuComponent getChild(int i) { return items.get(i); }
    public String getName() { return name; }
    public String getDescription() { return description; }
    public void print() {
        System.out.println("\n" + getName() + ", " + getDescription());
        System.out.println("---------------------");
        for (MenuComponent c : items) c.print(); // 遞歸調用
    }
}

// 客戶端:服務員
class Waitress {
    private MenuComponent allMenus;
    public Waitress(MenuComponent menus) { allMenus = menus; }
    public void printMenu() { allMenus.print(); }
}

優缺點分析

優點缺點
① 簡化客戶端代碼,統一處理葉子與容器① 設計過於通用,可能導致類層次過深
② 易於添加新類型的構件② 難以限制容器中允許的子構件類型
③ 符合開閉原則③ 在功能差異大的葉子/容器間強行統一接口可能不自然

設計原則體現

  • 單一職責原則:葉子負責具體業務,容器負責管理子節點
  • 開閉原則:新增構件類型無需修改現有代碼
  • 里氏替換原則:葉子與容器均可替換 Component 基類

總結

組合模式是處理樹形結構的利器。關鍵在於定義良好的 Component 接口,讓葉子與容器共享公共行為,並在容器中遞歸委派操作。菜單系統、文件目錄、組織架構圖都是其典型應用場景。

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