组合模式
将对象组合成树形结构以表示部分整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
Component
package com.hml.combination; public abstract class Component { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Component(String name) { this.name = name; } public abstract void add(Component c); public abstract void remove(Component c); public abstract void display(int depth); }
Composite
package com.hml.combination; import java.util.ArrayList; import java.util.List; public class Composite extends Component { private List<Component> children = new ArrayList<Component>(); public Composite(String name) { super(name); } @Override public void add(Component c) { children.add(c); } @Override public void remove(Component c) { children.remove(c); } @Override public void display(int depth) { for (int i = 0; i < children.size(); i++) { children.get(i).display(i); } } }
Leaf
package com.hml.combination; public class Leaf extends Component { public Leaf(String name) { super(name); } @Override public void add(Component c) { System.out.println("can't add to a leaf"); } @Override public void remove(Component c) { System.out.println("can't remove from a leaf"); } @Override public void display(int depth) { System.out.println("-" + depth + this.getName()); } }
Test
package com.hml.combination; public class Test { public static void main(String[] args) { Composite root = new Composite("root"); root.add(new Leaf("A")); root.add(new Leaf("B")); Composite com1 = new Composite("com1"); com1.add(new Leaf("C")); com1.add(new Leaf("D")); root.add(com1); Composite com2 = new Composite("com1"); com2.add(new Leaf("E")); com2.add(new Leaf("F")); root.add(com2); root.display(1); } }
类图
Leaf中有Add和Remove方法,这种方式叫做透明方式,也就是说在Component中声明所有用来管理子对象的方法,其中包含Add和Remove等。这样实Component接口的所有子类都具备了Add和Remove。这样的好处是叶子节点和枝节点对于外界没有区别,他们具备完全一致的行为接口。但是问题是实现格外的Add和remove没有任何意义。安全方式,也就是Component接口中不声明add和remove方法,那么子类Leaf也就不需要实现它们,而在composite声明所有用来管理子类对象的方法,这样做就不会出现刚才提到的问题,不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。
当需求中是体现部分与整体层次结构时,以及希望客户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式。