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

Java 設計模式之組合模式介紹

     編輯:Java 相關知識

組合模式:樹形結構實現「部分-整體」層次

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

核心角色

  • Component(抽象構件):定義葉子和容器的公共接口,聲明管理子對象的方法(add/remove/getChild)。
  • Leaf(葉子構件):無子對象,實現具體業務邏輯。
  • Composite(容器構件):包含子對象集合,實現管理子對象方法,業務邏輯遞調用子對象。

代碼範例:電腦設備價格計算

// 1. 抽象構件
public abstract class Equipment {
    protected String name;
    public Equipment(String name) { this.name = name; }
    public abstract double netPrice();
    public abstract double discountPrice();
    // 容器管理方法,默認拋異常或返回 false
    public boolean add(Equipment e) { throw new UnsupportedOperationException(); }
    public boolean remove(Equipment e) { throw new UnsupportedOperationException(); }
    public Iterator iterator() { return Collections.emptyIterator(); }
}

// 2. 葉子:磁盤
public class Disk extends Equipment {
    public Disk(String name) { super(name); }
    @Override public double netPrice() { return 100; }
    @Override public double discountPrice() { return 50; }
}

// 3. 容器抽象類
public abstract class CompositeEquipment extends Equipment {
    private List children = new ArrayList<>();
    public CompositeEquipment(String name) { super(name); }
    @Override public boolean add(Equipment e) { return children.add(e); }
    @Override public boolean remove(Equipment e) { return children.remove(e); }
    @Override public Iterator iterator() { return children.iterator(); }
    // 業務邏輯遞歸委派
    @Override public double netPrice() {
        return children.stream().mapToDouble(Equipment::netPrice).sum();
    }
    @Override public double discountPrice() {
        return children.stream().mapToDouble(Equipment::discountPrice).sum();
    }
}

// 4. 具體容器:機箱、機櫃
public class Chassis extends CompositeEquipment {
    public Chassis(String name) { super(name); }
    @Override public double netPrice() { return 200 + super.netPrice(); } // 自身價格 + 子設備
    @Override public double discountPrice() { return 100 + super.discountPrice(); }
}
public class Cabinet extends CompositeEquipment {
    public Cabinet(String name) { super(name); }
    @Override public double netPrice() { return 500 + super.netPrice(); }
    @Override public double discountPrice() { return 250 + super.discountPrice(); }
}

// 5. 客戶端
public class Client {
    public static void main(String[] args) {
        Cabinet cabinet = new Cabinet("機櫃");
        Chassis chassis = new Chassis("機箱");
        cabinet.add(chassis);
        chassis.add(new Disk("硬盤 1TB"));
        chassis.add(new Disk("SSD 512GB"));

        System.out.println("淨價: " + cabinet.netPrice());       // 統一調用
        System.out.println("折扣價: " + cabinet.discountPrice());
    }
}

模式優勢

  • 客戶端簡單:無需區分葉子和容器,統一調用 Component 接口。
  • 易於擴展:新增葉子或容器類無需修改客戶端代碼,符合開閉原則。
  • 結構靈活:可構建複雜的樹形結構。

應用場景

  • 文件系統(文件/目錄)、GUI 組件樹(容器/控件)、組織架構(員工/部門)、XML/HTML DOM 樹。
  • Jive 論壇中 ForumThread 包含多個 ForumMessage(回帖樹)即採用組合模式。

注意事項

在 Component 接口中聲明 add/remove 方法雖便於多態,但會導致 Leaf 類實現無意義的方法(拋異常)。替代方案:僅在 Composite 類中聲明管理方法,客戶端針對容器類型調用(犧牲部分透明性換取安全性)。

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