意图
为了保证客户端调用单对象与组合对象的一致性
黑猫的理解
就是相当与一棵大树,把树干和树叶组合到一起,统一管理。要管理,就需要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);
}