1. 程式人生 > >java23種設計模式——八、組合模式

java23種設計模式——八、組合模式

## 目錄 [java23種設計模式—— 一、設計模式介紹](https://www.cnblogs.com/codermy/p/13565137.html) [java23種設計模式—— 二、單例模式](https://www.cnblogs.com/codermy/p/13566365.html) [java23種設計模式——三、工廠模式](https://www.cnblogs.com/codermy/p/13569486.html) [java23種設計模式——四、原型模式](https://www.cnblogs.com/codermy/p/13571750.html) [java23種設計模式——五、建造者模式](https://www.cnblogs.com/codermy/p/13575590.html) [java23種設計模式——六、介面卡模式](https://www.cnblogs.com/codermy/p/13577408.html) [java23種設計模式——七、橋接模式](https://www.cnblogs.com/codermy/p/13580922.html) [java23種設計模式——八、組合模式](https://www.cnblogs.com/codermy/p/13580924.html) ## 介紹 組合模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的物件當作一個單一的物件。組合模式依據樹形結構來組合物件,用來表示部分以及整體層次。這種型別的設計模式屬於結構型模式,它建立了物件組的樹形結構。 這種模式建立了一個包含自己物件組的類。該類提供了修改相同物件組的方式。 組合模式類似樹形結構,上一層節點的包含多個下一層的節點,而下一層的節點只依附於一個上一層的節點。 ## 實現 我們先來看下組合模式的角色。 - Component抽象構建角色,抽象共有的方法和屬性, - Leaf葉子構件,葉子物件,沒有其他分支,類似於樹葉 - Composite數值構件,組合葉子和其他樹枝組合成一個完整的樹,類似於樹枝 通常大學裡都有很多個系,每個系又包含多個專業,每個專業也有多個班級。 首先有一個抽象學校類,即component角色 ```java /** * @author codermy * @createTime 2020/7/28 */ //學校 public abstract class School { //展示樹形結構 public abstract void display(String f); //新增分支 public void add(School branch){ throw new UnsupportedOperationException("不支援此功能"); }; //刪除分支 public void remove(School branch) { // 若葉子物件沒有這個功能,或子類未實現這個功能 throw new UnsupportedOperationException("不支援此功能"); } } ``` 現在有一個Branch類(即Composite角色)繼承了學校類,並實現其中方法。我們可以把它抽象的想成,學校的分院與專業的結構都一樣,所以新建它們都公用這一個類 ```java /** * @author codermy * @createTime 2020/7/28 * 分院 */ public class Branch extends School { //學校集合 private List schoolList = new ArrayList<>(); private String name; public Branch(String name){ this.name=name; } @Override public void display(String f) { System.out.println(f + name); // 如果還包含其他子元件,那麼就輸出這些子元件物件 if (null != schoolList) { // 新增一個空格,表示向後縮排一個空格 f += "---"; // 輸出當前物件的子元件物件 for (School school : schoolList) { // 遞迴地進行子元件相應方法的呼叫,輸出每個子元件物件 school.display(f); } } } public void add(School branch){ schoolList.add(branch); } public void remove(School branch){ schoolList.remove(branch); } } ``` 而學校裡最小的單元是班級,新建這個類(即Leaf) ```java /** * @author codermy * @createTime 2020/7/28 */ public class Class extends School { private String name; public Class(String name){ this.name = name; } @Override public void display(String f) { System.out.println(f + "-"+ name); } } ``` client類測試 ```java /** * @author codermy * @createTime 2020/7/28 */ public class Client { public static void main(String[] args) { //新建一個學校 School university = new Branch("南京大學"); //新建分院 School branch1 = new Branch("計算機與軟體學院"); School branch2 = new Branch("外國語學院"); //新建專業 School profession1 = new Branch("軟體工程"); School profession2 = new Branch("網路工程"); //新建班級 profession1.add(new Class("軟體1801")); profession1.add(new Class("軟體1802")); branch1.add(profession1); branch1.add(profession2); university.add(branch1); university.add(branch2); university.display("-"); } } ``` 輸出 ```bash -南京大學 ----計算機與軟體學院 -------軟體工程 -----------軟體1801 -----------軟體1802 -------網路工程 ----外國語學院 ``` ## 優缺點 **優點:** - 1、高層模組呼叫簡單。 - 2、節點自由增加。 - 3、可以清楚地定義分層次的複雜物件,表示物件的全部或部分層次,使得增加新構件也更容易。 **缺點:** - 1、在使用組合模式時,其葉子和樹枝的宣告都是實現類,而不是介面,違反了依賴倒置原則。 - 2、使設計變得更加抽象,物件的業務規則如果很複雜,則實現組合模式具有很大挑