軟體設計模式白話文系列(十二)組合模式

1、模式描述

組合模式屬於結構型模式,把多個對象組成樹狀結構來表示局部與整體,這樣用戶可以以相同的方式對待單個對象和組合對象。需要注意的是這裡的組合和之前系列中,我們說的組合關係(可以將已有對象納入新對象中,使之成為新對象的一部分,新對象可以調用已有對象的功能)是兩個完全不同的概念哈。

2、模式結構

  • 抽象節點類:樹枝節點類和葉子節點類的父類,定義它們的行為規範和共有屬性。
  • 樹枝節點類:存在下級節點,需要儲存葉子節點類的集合。擁有一個或者多個抽象節點對象
  • 葉子節點類:沒有下級節點,組合模式最下最小單位。

3、實現邏輯

抽象出共性介面,樹枝節點類和葉子節點類同時實現介面,樹枝節點類引用介面集合對象,葉子節點引用上級樹枝節點對象。

4、實戰程式碼

我們知道文件系統就是一個樹狀結構,文件夾下面會有文件夾或者文件。在這裡文件夾就是樹枝節點類,文件就是葉子節點類

/**
 * 抽象節點類
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-16 00:02:58
 */
public interface Node {
    String getPath();
    void print();
}

/**
 * 樹枝節點類
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-16 00:04:23
 */
public class Directory implements Node {
    private String path;
    private List<Node> nodes = new ArrayList<>();

    public Directory(String path) {
        this.path = path;
    }

    public Directory(Directory parentPath, String dirName) {
        parentPath.addChild(this);
        this.path = parentPath.getPath() + "/" + dirName;
    }

    @Override
    public String getPath() {
        return this.path;
    }

    @Override
    public void print() {
        System.out.println("/" + path);
        for (Node node : this.nodes) {
            node.print();
        }
    }

    public void addChild(Node node) {
        this.nodes.add(node);
    }
}

/**
 * 葉子節點類
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-16 00:05:36
 */
public class File implements Node {
    private String filename;
    private Directory directory;

    public File(Directory directory, String filename) {
        directory.addChild(this);
        this.filename = filename;
    }

    @Override
    public String getPath() {
        return this.directory.getPath() + filename;
    }

    @Override
    public void print() {
        System.out.println("--" + filename);
    }

}

/**
 * 測試類
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-16 07:43:52
 */
public class Client {
    public static void main(String[] args) {
        Directory rootDir = new Directory("root");
        Directory optDir = new Directory(rootDir,"opt");
        Directory ectDir = new Directory(rootDir,"ect");
        Directory confDir = new Directory(optDir,"conf");
        File nginxConf = new File(confDir, "nginx.conf");
        File dockerfile = new File(confDir, "Dockerfile");
        Directory userDir = new Directory(ectDir, "eajur");

        rootDir.print();
        System.out.println("-----------------");
        optDir.print();
        System.out.println("-----------------");
        ectDir.print();
    }
}

5、適用場景

組合模式的目的就是將一系列相似對象組設置為樹形結構,方便對某一個節點下的內容進行操作。所以組合模式適用於出現樹形結構的地方。例如:多級菜單顯示,文件目錄顯示,多級目錄呈現等樹形結構數據的操作。