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

設計模式-組合模式

組合模式

定義:將物件組合成樹形結構以表示部分整體得層次結構。組合模式使使用者對單一物件和組合物件使用具有一致性。

使用場景:希望使用者忽略組合物件和單個物件的不同,統一的使用組合結構中的所有物件。如檔案、資料夾的管理。

有兩種方式:

  1. 透明方式:

由於抽象構件聲明瞭所有子類中的全部方法,所以客戶端無須區別樹葉物件和樹枝物件,對客戶端來說是透明的。但缺點是樹葉構件本來沒有add(),remove()等方法,卻要實現他們(空實現、拋異常),會帶來安全問題。
2. 安全方式

這種方式中,將管理子構件的方法移到樹枝構件中,這樣子構件和抽象構件中就不需要寫這些冗餘的方法。但是客戶端呼叫的時候就要知道樹葉構件和樹枝構件的存在,失去了透明性。

程式碼示例:

public interface IFile {

    void delete();
    String getName();
    void createNewFile(String name);
    void deleteFile(String name);

}

public class File implements IFile{
    
    private String name;
    private IFile folder;
    
    public File(String name,IFile folder) {
        super();
        this.name = name;
        this.folder = folder;
    }
    
    public String getName() {
        return name;
    }

    public void delete() {
        folder.deleteFile(name);
        System.out.println("---刪除[" + name + "]---");
    }

    //檔案不支援建立新檔案
    public void createNewFile(String name) {
        throw new UnsupportedOperationException();
    }
    //檔案不支援刪除檔案
    public void deleteFile(String name) {
        throw new UnsupportedOperationException();
    }
    //檔案不支援獲取下面的檔案列表
    public IFile getIFile(int index) {
        throw new UnsupportedOperationException();
    }

}
public class Folder implements IFile {

    private String name;
    private IFile folder;
    private List<IFile> files;

    public Folder(String name, IFile folder) {
        this.name = name;
        this.folder = folder;
        files=new ArrayList<>();
    }

    @Override
    public void delete() {
        List<IFile> copy = new ArrayList<IFile>(files);
        System.out.println("------------刪除子檔案-------------");
        for (IFile file:copy){
            file.delete();
        }
        if (folder != null) {
            folder.deleteFile(name);
        }
        System.out.println("---刪除[" + name + "]---");
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void createNewFile(String name) {
        if (name.contains(".")) {
            files.add(new File(name,this));
        }else {
            files.add(new Folder(name,this));
        }
    }

    @Override
    public void deleteFile(String name) {
        for (IFile file : files) {
            if (file.getName().equals(name)) {
                files.remove(file);
                break;
            }
        }
    }
}

返回目錄