Composite模式属于对象的结构模式,有时候又叫部分-整体模式,它将对象组织到树结构中,把部分与整体的关系用树结构表示出来,例如一个文件系统就是个很典型的Composite模式系统。
Composite模式的三个角色:
1 Component(根节点) 为组合中的对象声明接口,在适当情况下,实现所有类共有接口的缺省行为,声明一个接口用于访问和管理Component的子组件
2 Leaf(树叶),在组合中表示叶节点对象,叶节点没有子节点,也就是说该对象是不存在子对象的
3 Composite(树枝),定义子部件的某些部件的行为,存储子部件,即该对象存在下级子对象的对象,实现component给出的所有管理子对象的方法
Composite模式的实现可以不提供对象的管理方法,但是Composite模式必须在合适的地方提供子对象的管理方法,在什么地方声明子对象的管理方法,如:add() remove()等等,这是值得思考的,所以Composite模式可以分成两种形式:透明式和安全式。如图:
安全式代码实现:
package composite; public interface Component { Composite getComposite(); void sampleOperation(); } package composite; public class Leaf implements Component { @Override public Composite getComposite() { // TODO Auto-generated method stub return null; } @Override public void sampleOperation() { // TODO Auto-generated method stub } } package composite; import java.util.Enumeration; import java.util.Vector; public class Composite implements Component { private Vector componentVector = new Vector(); @Override public Composite getComposite() { return this; } @Override public void sampleOperation() { Enumeration e = getComponents(); while(e.hasMoreElements()) { ((Component) e.nextElement()).sampleOperation(); } } public void addComponent(Component c) { componentVector.add(c); } public void delComponent(Component c) { componentVector.remove(c); } public Enumeration getComponents() { return componentVector.elements(); } }
透明式代码实现:
package composite; import java.util.Enumeration; public interface Component2 { Composite2 getComposite(); void sampleOperation(); void addComponent(Component2 c); void delComponent(Component2 c); Enumeration getComponents(); } package composite; import java.util.Enumeration; import java.util.Vector; public class Composite2 implements Component2 { private Vector componentVector = new Vector(); @Override public void addComponent(Component2 c) { // TODO Auto-generated method stub componentVector.add(c); } @Override public void delComponent(Component2 c) { // TODO Auto-generated method stub componentVector.remove(c); } @Override public Enumeration getComponents() { // TODO Auto-generated method stub return componentVector.elements(); } @Override public Composite2 getComposite() { // TODO Auto-generated method stub return this; } @Override public void sampleOperation() { Enumeration e = getComponents(); while(e.hasMoreElements()) { ((Component) e.nextElement()).sampleOperation(); } } } package composite; import java.util.Enumeration; public class Leaf2 implements Component2 { @Override public void addComponent(Component2 c) { // TODO Auto-generated method stub } @Override public void delComponent(Component2 c) { // TODO Auto-generated method stub } @Override public Enumeration getComponents() { // TODO Auto-generated method stub return null; } @Override public Composite2 getComposite() { // TODO Auto-generated method stub return null; } @Override public void sampleOperation() { // TODO Auto-generated method stub } }
显然,透明式是不够安全的,因为树叶类对象和树枝(Composite)类对象是有实质的区别的;而安全式虽然够安全,但是却不够透明,因为树叶类和树枝类具有不同的接口,所以,在使用哪种Composite模式时,需要根据软件的具体情况对这两种形式做取舍。