意圖
爲了保證客戶端調用單對象與組合對象的一致性
黑貓的理解
就是相當與一棵大樹,把樹幹和樹葉組合到一起,統一管理。要管理,就需要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);
}