設計模式 - 混合模式(整體-部分模式)


混合模式(整體-部分模式):將對象組合成樹形結構以表示“部分-整體”的層次結構,使單個對象(葉)和復合對象(枝)的使用具有一致性
核心:使對葉和枝的操作具備一致性,①簡化客戶端的使用,②節點自由增加
角色:

  • 抽象節點(Component):
    • (安全模式下)定義形成組合的葉和枝之間的共性部分(枝作為個體相關的操作) --> 需要使用枝的組合相關操作時需轉型
    • (透明模式下)在共性部分外,還會提供枝的組合相關的操作 --> 對葉子對象使用枝的組合相關的功能時,可能出現錯誤
  • 樹枝節點(Composite):整體部分(也存在作為個體時的功能),組合葉子節點和下一層樹枝節點
    ① 存在作為組合相關的操作
    ② 存在作為個體相關的操作
  • 葉子節點(Leaf):個體部分,只實現個體相關的操作

使用場景:對象層次具備組合和個體的樹形關系,且客戶端希望忽略組合對象(枝)和個體對象(葉)的差異時,(即:枝對象同時具備組合部分的功能和個體部分的功能)

安全模式

// 抽象父類,維護葉和枝之間的共性(此時,共性多為枝作為個體部分的操作)
public abstract class Directory {
    protected String name;

    protected Directory(String name) {
        this.name = name;
    }

    public abstract void show(String prefix);
}
// 枝節點,實現抽象父類方法之外,還要實現作為組合功能的操作
public class Folder extends Directory{
    // 組合葉子節點和下一層樹枝節點
    List<Directory> directorys = new ArrayList<>();

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

    @Override
    public void show(String prefix) {
        System.out.println(prefix + "Folder : " + name);
    }

    public void addDirectory(Directory directory){
        directorys.add(directory);
    }

    public void remoceDirectory(Directory directory){
        directorys.remove(directory);
    }

    public List<Directory> getDirectorys(){
        return directorys;
    }

    public void listDirectorys(String prefix){
        for(Directory directory : directorys){
            if(directory instanceof Folder) {
                directory.show(prefix);
                ((Folder) directory).listDirectorys(prefix + "    ");
            }else {
                directory.show(prefix);
            }
        }
    }
}
// 葉節點
public class File extends Directory{
    public File(String name) {
        super(name);
    }

    @Override
    public void show(String prefix) {
        System.out.println(prefix + "File : " + name);
    }
}

透明模式

// 抽象父類,維護葉和枝之間的共性,以及枝的組合相關操作
public abstract class Directory {
    protected String name;

    protected Directory(String name) {
        this.name = name;
    }

    public abstract void show(String prefix);

    public abstract boolean isFolder();

    // 枝的組合相關操作
    public abstract void addDirectory(Directory directory);

    public abstract void removeDirectory(Directory directory);

    public abstract List<Directory> getDirectorys();

    public abstract void listDirectorys(String prefix);
}
// 枝節點,實現抽象父類方法
public class Folder extends Directory {
    List<Directory> directorys = new ArrayList<>();

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

    @Override
    public void show(String prefix) {
        System.out.println(prefix + "Folder : " + name);
    }

    @Override
    public boolean isFolder() {
        return true;
    }

    public void addDirectory(Directory directory){
        directorys.add(directory);
    }

    public void removeDirectory(Directory directory){
        directorys.remove(directory);
    }

    public List<Directory> getDirectorys(){
        return directorys;
    }

    public void listDirectorys(String prefix){
        for(Directory directory : directorys){
            if(directory instanceof Folder) {
                directory.show(prefix);
                ((Folder) directory).listDirectorys(prefix + "    ");
            }else {
                directory.show(prefix);
            }
        }
    }
}
// 葉節點,對於組合相關的操作,需做一定的拒絕處理
public class File extends Directory {
    public File(String name) {
        super(name);
    }

    @Override
    public void show(String prefix) {
        System.out.println(prefix + "File : " + name);
    }

    @Override
    public boolean isFolder() {
        return false;
    }

    @Override
    public void addDirectory(Directory directory) {
        System.out.println("Not folder, do nothing!");
    }

    @Override
    public void removeDirectory(Directory directory) {
        System.out.println("Not folder, do nothing!");
    }

    @Override
    public List<Directory> getDirectorys() {
        return null;
    }

    @Override
    public void listDirectorys(String prefix) {
        System.out.println("Not folder, do nothing!");
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM