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

codermy發表於2020-08-29

目錄

java23種設計模式—— 一、設計模式介紹
java23種設計模式—— 二、單例模式
java23種設計模式——三、工廠模式
java23種設計模式——四、原型模式
java23種設計模式——五、建造者模式
java23種設計模式——六、介面卡模式
java23種設計模式——七、橋接模式
java23種設計模式——八、組合模式

介紹

組合模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的物件當作一個單一的物件。組合模式依據樹形結構來組合物件,用來表示部分以及整體層次。這種型別的設計模式屬於結構型模式,它建立了物件組的樹形結構。

這種模式建立了一個包含自己物件組的類。該類提供了修改相同物件組的方式。

組合模式類似樹形結構,上一層節點的包含多個下一層的節點,而下一層的節點只依附於一個上一層的節點。

實現

我們先來看下組合模式的角色。

  • Component抽象構建角色,抽象共有的方法和屬性,
  • Leaf葉子構件,葉子物件,沒有其他分支,類似於樹葉
  • Composite數值構件,組合葉子和其他樹枝組合成一個完整的樹,類似於樹枝

通常大學裡都有很多個系,每個系又包含多個專業,每個專業也有多個班級。

首先有一個抽象學校類,即component角色

/**
 * @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角色)繼承了學校類,並實現其中方法。我們可以把它抽象的想成,學校的分院與專業的結構都一樣,所以新建它們都公用這一個類

/**
 * @author codermy
 * @createTime 2020/7/28
 * 分院
 */
public class Branch extends School {
    //學校集合
    private List<School> 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)

/**
 * @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類測試

/**
 * @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("-");
    }
}

輸出

-南京大學
----計算機與軟體學院
-------軟體工程
-----------軟體1801
-----------軟體1802
-------網路工程
----外國語學院

優缺點

優點:

  • 1、高層模組呼叫簡單。
  • 2、節點自由增加。
  • 3、可以清楚地定義分層次的複雜物件,表示物件的全部或部分層次,使得增加新構件也更容易。

缺點:

  • 1、在使用組合模式時,其葉子和樹枝的宣告都是實現類,而不是介面,違反了依賴倒置原則。
  • 2、使設計變得更加抽象,物件的業務規則如果很複雜,則實現組合模式具有很大挑戰性。

相關文章