将对象组合成树形结构以表示“部分-整体”的层次结构,Composite模式使得用户对单个对象和组合对象的使用具有一致性。例如,在office中绘图,可以将若干图形组合成为组,当对组操作时会影响所有的组内元素,这里就是把组合图形作为单个元素来看待。
使用Composite模式时可以表示对象的部分-整体层次结构,可以让你忽略组合对象和单个对象的不同,它还可以简化客户代码,使得更容易增加新类型的组件,使你的设计更加一般化。
public interface Component {
public String getName();
public void setGroup(String group);
//
public String operation();
public void add(Component component);
public void remove(Component component);
public Component getChild(String name);
}
public class Composite implements Component {
private String name = null;
private String group = null;
public Composite(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setGroup(String group) {
this.group = group;
}
public String toString() {
return group + "-" + name;
}
//
private Map<String, Component> childs = new HashMap<>();
@Override
public String operation() {
StringBuilder ss = new StringBuilder();
ss.append(toString()+":[");
for (String name : childs.keySet()) {
ss.append(childs.get(name).operation()+",");
}
ss.append("]");
return ss.toString();
}
@Override
public void add(Component component) {
if (component != null) {
component.setGroup(name);
childs.put(component.getName(), component);
}
}
@Override
public void remove(Component component) {
childs.remove(component);
}
@Override
public Component getChild(String name) {
return childs.get(name);
}
}
public class Leaf implements Component {
private String name = null;
private String group = null;
public Leaf(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setGroup(String group) {
this.group = group;
}
public String toString() {
return group + "-" + name;
}
//
@Override
public String operation() {
return toString();
}
@Override
public void add(Component component) {
// do nothing
}
@Override
public void remove(Component component) {
// do nothing
}
@Override
public Component getChild(String name) {
// do nothing
return null;
}
}
public class Client {
/**构成结构为
* <pre>
* root
* ____|____
* | |
* node leaf1
* __|__
* | |
* leaf2 leaf3
* </pre>
* */
@Test
public void test() {
Component leaf1 = new Leaf("leaf1");
Component leaf2 = new Leaf("leaf2");
Component leaf3 = new Leaf("leaf3");
Component root = new Composite("root");
Component node = new Composite("node");
root.add(leaf1);
root.add(node);
node.add(leaf2);
node.add(leaf3);
System.out.println(root.operation());
}
}
组合模式的最终效果看起来就像一棵树,当调用最上层root的operation时,下层的child的operation方法就会被级联调用,故可以将它们每个组都看成一个整体。这里就是在Composite类中存储了一个Map用于存储所有的子Component,当遍历时,就直接遍历这个Map。在使用组合模式时也可以在类中加入父组件的引用,方便父组件对子组件的管理,而且需要最大化父组件的接口,以方便各种对组件的操作。