组合模式
1.定义
将对象组合成树形结构,以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
2.示例代码
商品分类树形结构,使得类别和叶子节点通过统一的组件对象访问。
/*抽象组件对象,为组合中的对象声明接口,实现接口的缺省行为*/ public abstract class Component{ //输出组件自身的名称 public abstract void printStruct(String preStr); /*向组合对象中添加组件对象*/ public void addChild(Component child){ throw new UnsupportedOperationException("对象不支持这个方法"); } /*移除组件对象*/ public void removeChild(Component child){ throw new UnsupportedOperationException("对象不支持这个方法"); } /*根据索引获取组件对象*/ public Component getChildren(int index){ throw new UnsupportedOperationException("对象不支持这个方法"); } }
/*叶子对象实现*/ public class Leaf extends Component{ //叶子对象名称 private String name = ""; public Leaf(String name){ this.name = name; } //输出叶子对象结构 public void printStruct(String preStr){ System.out.println(preStr + "-" + name); } } /*组合对象实现,可以包含其他组合对象和叶子节点*/ public class Composite extends Component{ //用来存储组合对象包含的子组件对象 private List<Component> childComponents = null; //组合对象名字 private String name = ""; public Composite(String name){ this.name = name; } public void addChild(Component child){ if(childComponents == null){ childComponents = new ArrayList<Component>(); } childComponents.add(child); } public void printStruct(String preStr){ //先把自己输出去 System.out.println(preStr+ "-" + name); //如果还包含自组件对象,那么就输出子组件对象 if(this.childComponents != null){ //添加空格缩进 preStr += " "; //输出子组件对象 for(Component c : childComponents){ c.printStruct(preStr); } } } }
/*客户端操作不需要区分叶子节点和组合对象*/ public class Client{ public static void main(String args[]){ //定义所有组合对象 Component root = new Component("服装"); Component c1 = new Component("男装"); Component c2 = new Component("女装"); //定义所有叶子对象 Component leaf1 = new Leaf("衬衣"); Component leaf2 = new Leaf("夹克"); Component leaf3 = new Leaf("裙子"); Component leaf4 = new Leaf("套装"); //按照结构组合对象和叶子对象 root.addChild(c1); root.addChild(c2); c1.addChild(leaf1); c1.addChild(leaf2); c2.addChild(leaf3); c2.addChild(leaf4); //调用根对象输出整棵树 root.printStruct(""); } }
3.实际应用
组合模式的目的是让客户端不在区分操作的是组合对象还是叶子对象,而是以统一的方式来操作,实现这个目标的关键之处,是设计一个抽象的组件类,让它可以代表组合对象和叶子对象,这也意味着,所有可以使用对象树来描述或者操作的功能,都可以考虑使用组合模式,比如读取xml文件,或是对语句进行语法解析等。
组合模式的本质:统一叶子对象和组合对象