天天看點

實戰java設計模式(十)組合模式1 介紹2 例子3 例子升華4 總結

目錄

  • 1 介紹
  • 2 例子
    • 2.1 檔案夾(檔案)抽象父類
    • 2.2 添加一個接口擴充卡(可選)
    • 2.3 葉子節點的實作
    • 2.4 非葉子節點
    • 2.5 測試主類
  • 3 例子升華
  • 4 總結
    • 4.1 核心角色
    • 4.2 核心代碼結構

1 介紹

部分整體模式,是用于把一組相似的對象當作一個單一的對象。

2 例子

這樣的情況非常使用于檔案夾存放檔案的情況,檔案夾可以多級,如果為每級檔案夾都定義一個類的話成本是非常高的。

2.1 檔案夾(檔案)抽象父類

//抽象父類
abstract class FileFolder {
    //展示一下這個檔案夾
    public abstract void show();
    //添加
    public abstract void add(FileFolder fileFolder);
    //移除
    public abstract void remove(FileFolder fileFolder);
}
           

注意:該父類辨別某一級檔案夾,有一些自己的方法,比如顯示該目錄下所有的檔案夾或者檔案等等,删除等等,他也不知道自己下面還有多少級,反正提供了一個把自己類型的作為形參的抽象方法。

2.2 添加一個接口擴充卡(可選)

//添加一個接口擴充卡
abstract class FileFolderAdapter extends FileFolder {
    @Override
    public void show() {
    }

    @Override
    public void add(FileFolder fileFolder) {
    }

    @Override
    public void remove(FileFolder fileFolder) {
    }
}
           

接口擴充卡前面說到了,就是接口的有些方法想實作,有些不想,就是采用了這樣一個方式,我僅僅是為了撿便宜,在葉子節點的時候不想實作add和remove方法。

2.3 葉子節點的實作

//葉子節點
class Leaf1 extends FileFolderAdapter {

    @Override
    public void show() {
        System.out.println("視訊");
    }
}
class Leaf2 extends FileFolderAdapter {

    @Override
    public void show() {
        System.out.println("圖檔");
    }
}
class Leaf3 extends FileFolderAdapter {

    @Override
    public void show() {
        System.out.println("音頻");
    }
}
           

定義了三種葉子節點,可以表示不同的檔案類型。

2.4 非葉子節點

//非葉子節點
class FileFolderUse extends FileFolderAdapter{
    //定義一個存儲檔案的容器
    List<FileFolder> list=new ArrayList<>();
    @Override
    public void show() {
        System.out.println("檔案夾");
        for (FileFolder i:list){
            i.show();
        }
    }

    @Override
    public void add(FileFolder fileFolder) {
        list.add(fileFolder);
    }

    @Override
    public void remove(FileFolder fileFolder) {
       list.remove(fileFolder);
    }
}
           

存儲fileFolder的容器可以任意,數組、集合、清單、連結清單、map都可以。

2.5 測試主類

public class Main {
    public static void main(String[] args) {
        //先定義葉子節點
        FileFolder leaf1=new Leaf1();
        FileFolder leaf2=new Leaf2();
        FileFolder leaf3=new Leaf3();
        FileFolder leaf4=new Leaf3();

        //定義一個檔案夾B把它放進去
        FileFolder B=new FileFolderUse();
        B.add(leaf1);
        B.add(leaf2);
        B.add(leaf3);
        B.add(leaf4);

        //再定義一個檔案夾
        FileFolder A=new FileFolderUse();
        A.add(B);

        //顯示
        A.show();
    }
}
           

3 例子升華

組合模式的最精髓的在于其抽象父類的設計,裡面定義的操作方法的參數是抽象父類的資料類型,很好的實作了不同類型對象的統一操作和遞歸操作。

4 總結

4.1 核心角色

  • 抽象父類:定義了一種統一的資料類型,及其遞歸操作。
  • 葉子節點實作:葉子節點的部分方法實作會不一樣。
  • 非葉子節點的實作:非葉子節點會實作所有方法。

4.2 核心代碼結構

抽象父類的設計,那種自己操作自己的設計思路值得學習。