Java設計模式之合成模式(Composite)

意圖
爲了保證客戶端調用單對象與組合對象的一致性
黑貓的理解
就是相當與一棵大樹,把樹幹和樹葉組合到一起,統一管理。要管理,就需要getComponent,removeComponent,addComponent等方法,合成模式主要分爲安全式和透明式(不安全)的,由於要想要滿足這種方式,一般都是透明式的
寫個例子
樹幹,統一管理的,透明的

//定義樹幹
public abstract class Tree {
    //打印組件自身的名稱,具體實體構體比如樹葉也有,故必須被繼承
    public abstract void printStruct(String preStr);
    //添加大樹上的一個組件,只有樹枝有,不不應該是必須被重寫的
    public void addComponent(Tree component){};
    //移除一個組件,只有樹枝有
    public void removeComponent(int index){};
    //聚集管理方法,返回所有子構建的對象,只有樹枝有
    public List<Tree> getComponent(){
        return null;
    };
}

定義樹枝

//樹枝類,要被統一管理當然要去實現樹幹了
public class Branch implements Tree{
    //是個樹枝,總得有個名字
    private String name;
    //萬一樹枝上面還有樹枝呢,弄個集合管理
    private List<Tree> childComponents = new ArrayList<Tree>();
    //構造方法傳入名字,當然也可以用set
    public Branch(String name){
        this.name = name;
    }

    @Override
    public void printStruct(String preStr) {
        //先打印出自己的名字
        System.out.println(preStr + "+" + this.name);
        //判斷這個樹枝下面還有沒其他樹枝或者樹葉
        if(this.childComponents != null){
            //添加兩個空格
            preStr += "  ";
            //輸出當前對象的子對象
            for(Tree c: childComponents){
                //一直遞歸到打印完所有
                c.printStruct(preStr);
            }
        }
    }

    @Override
    public void addComponent(Tree component) {
        //添加一個樹枝或樹葉
        childComponents.add(component);
    }

    @Override
    public void removeComponent(int index) {
        childComponents.remove(index);
    }

    @Override
    public List<Tree> getComponent() {
        return childComponents;
    }

}

樹葉類,樹葉上不能再有兒子了,相當與實體類

//一樣的繼承樹幹,但是只需要重寫打印名字方法
public class Leaf extends Tree{

    //一樣的,後面都是傳入名字
    private String name;
    public Leaf(String name){
        this.name = name;
    }


    @Override
    public void printStruct(String preStr) {
            System.out.println(preStr + "-" + name);
    }
}

寫一個客戶端類統一管理

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //統一管理,所以都是向上轉型成Tree的對象
        //樹枝
        Tree branch1 = new Branch("左邊大樹枝");
        Tree branch2 = new Branch("左邊小樹枝");
        Tree branch3 = new Branch("右邊大樹枝");
        Tree branch4 = new Branch("樹枝");
        //樹葉
        Tree leaf1 = new Leaf("左邊樹葉");
        Tree leaf2 = new Leaf("右邊樹葉");
        //添加到組件中
        branch4.addComponent(branch1);
        branch4.addComponent(branch3);
        branch1.addComponent(branch2);
        branch2.addComponent(leaf1);
        branch3.addComponent(leaf2);
        //打印下大樹
        branch4.printStruct("大樹:");
    }

}

安全式的合成模式只是將組件老大(Tree)換成了一個抽象類,這樣就在具體的構建類中寫add,remove方法,樹葉只和具體構建類只重寫這個打印方法,但是這樣不就只能用具體構建類管理add,remove方法,父類接口是管理不了的,樹葉也是。這樣就是安全的,但是不透明瞭,不能打到用一個類統一管理。

public interface Tree {
    //打印組件自身的名稱,具體實體構體比如樹葉也有,故必須被繼承
    public abstract void printStruct(String preStr);

}
發佈了36 篇原創文章 · 獲贊 30 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章