1. 程式人生 > >設計模式 --- 組合模式

設計模式 --- 組合模式

1.定義

將物件組合成樹形結構以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。

 

2.使用場景

表示物件的整體-部分層次結構時

從一個整體能夠獨立出部分模組或功能的場景

 

3.簡單實現

以作業系統的檔案系統為例。

//抽象檔案和資料夾
abstract class Dir{
    //儲存資料夾下的所有檔案
    List<Dir> list = new ArrayList<>();
    private String name;//檔案或者資料夾名稱
    public Dir(String name){
        this.name = name;
    }

    //新增檔案或資料夾
    abstract void addDir(Dir dir);
    //移除檔案或資料夾
    abstract void removeDir(Dir dir);
    //清空資料夾下所有元素
    abstract void clear();
    //輸出資料夾結構目錄
    abstract void print();
    //獲取資料夾下所有的資料夾或檔案
    abstract List<Dir> getFiles();
    //獲取檔案或資料夾名稱
    public String getName() {
        return name;
    }
}

//資料夾
class Folder extends Dir{

    public Folder(String name) {
        super(name);
    }

    @Override
    void addDir(Dir dir) {
        list.add(dir);
    }

    @Override
    void removeDir(Dir dir) {
        list.remove(dir);
    }

    @Override
    void clear() {
        list.clear();
    }

    @Override
    void print() {
        System.out.print(getName() + " ( ");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Dir dir = (Dir) iterator.next();
            dir.print();
            if (iterator.hasNext()){
                System.out.print(" , ");
            }
        }
        System.out.print(" ) ");
    }

    @Override
    List<Dir> getFiles() {
        return list;
    }
}

//檔案
class File extends Dir{

    public File(String name) {
        super(name);
    }

    @Override
    void addDir(Dir dir) {
        throw new UnsupportedOperationException("檔案物件不支援該操作");
    }

    @Override
    void removeDir(Dir dir) {
        throw new UnsupportedOperationException("檔案物件不支援該操作");
    }

    @Override
    void clear() {
        throw new UnsupportedOperationException("檔案物件不支援該操作");
    }

    @Override
    void print() {
        System.out.print(getName());
    }

    @Override
    List<Dir> getFiles() {
        throw new UnsupportedOperationException("檔案物件不支援該操作");
    }
}

public class ComponentMode {
    public static void main(String[] args){
        //構造一個目錄物件表示"C"盤
        Dir dirC = new Folder("C:");
        //新增一個檔案
        dirC.addDir(new File("IamFile.exe"));
        //新增三個資料夾
        Dir FolderA = new Folder("FolderA");
        dirC.addDir(FolderA);
        Dir FolderB = new Folder("FolderB");
        dirC.addDir(FolderB);
        Dir FolderC = new Folder("FolderC");
        dirC.addDir(FolderC);
        //A目錄下2個檔案
        FolderA.addDir(new File("aaa.txt"));
        FolderA.addDir(new File("aaa2.txt"));
        //C目錄下一個檔案
        FolderC.addDir(new File("ccc.txt"));

        //輸出目錄結構
        dirC.print();

    }
}

輸出:

 

4.小結

優點:

組合模式可以清楚定義分層次的複雜物件,表示物件的全部或者部分層次,它讓高層模組忽略了層次差異,方便對整個層次結構控制。

高層模組可以一致地使用一個組合結構或者其中單個物件,不必關係處理的是單個物件還是整個組合結構,簡化了高層模組的程式碼。

在組合模式中增加新的枝幹結構和葉子構件很方便,無需對現有類庫進行任何修改。

對樹形結構面向物件提供了一種靈活的解決方案,通過遞迴可以形成複雜的樹形結構,但對樹形結構的控制確非常簡單。

缺點:

在新增構件時不好對枝幹中的構件型別進行限制,必須進行類的檢查來實現,現實過程比較複雜。