树形结构在日常生活中是非常常见的,比如组织机构的这几,软件菜单的设计等,这些属性结构,他们的叶子节点和父节点在行为上基本是一致的。只是在父节点上可能又包含了子节点。这类应用在软件设计中,如果更好的来实现呢?这样我们就引出了下面对于组合模式的简单介绍:
组合模式(Composite)是整体与部分的关系,一个典型的应用就是树型结构,组合模式可以抽象出三种角色,分别为抽象构建角色(Component)、树枝构建角色(Composite)、树叶构建角色(Leaf).
抽象构件角色Component:它为组合中的对象声明接口,也可以为共有接口实现缺省行为。
树叶构件角色Leaf:在组合中表示叶节点对象——没有子节点,实现抽象构件角色声明的接口。
树枝构件角色Composite:在组合中表示分支节点对象——有子节点,实现抽象构件角色声明的接口;存储子部件。
下面简单的从原理图来理解这个组合模式:
然后应用到了具体的实力,我简单的举例,比如现在我们的年级,在专业分流之前我们四个班级的,电气6、7、8、9班,然后通过一个Composite类对这四个班级的人数的统计,实例如下:
首先设计的是一个年级接口,定义了一个getCount方法获得这个年级所属班级的人数,从而达到一个一级一级节点的遍历,班级通过实现统一的接口,调用者对单一对象和组合对象的操作具有一致性。
package com.designpattern.composite; public interface Grade { public int getCount(); }然后分别写了四个班级的代码:
package com.designpattern.composite; public class ElectricalClass6 implements Grade { @Override public int getCount() { return 53; } }
package com.designpattern.composite; public class ElectricalClass7 implements Grade { @Override public int getCount() { return 68; } }
package com.designpattern.composite; public class ElectricalClass8 implements Grade { @Override public int getCount() { return 70; } }
package com.designpattern.composite; public class ElectricalClass9 implements Grade { @Override public int getCount() { return 69; } }
package com.designpattern.composite; import java.util.ArrayList; import java.util.List; public class Composite implements Grade { private List list = new ArrayList(); public Composite add(Grade grade) { list.add(grade); return this; } public Grade getChild(int i) { return (Grade) list.get(i); } @Override public int getCount() { int count = 0; for (int i = 0; i < list.size(); i++) { Grade grade = (Grade) list.get(i); count += grade.getCount(); } return count; } public Composite remove(Grade grade) { list.remove(grade); return this; } }
composite.add(new ElectricalClass6()).add(new ElectricalClass7());
package com.designpattern.composite; public class Client { public static void main(String[] args) { Composite grade = new Composite(); ElectricalClass6 class6 = new ElectricalClass6(); ElectricalClass7 class7 = new ElectricalClass7(); ElectricalClass8 class8 = new ElectricalClass8(); ElectricalClass9 class9 = new ElectricalClass9(); grade.add(class6).add(class7); System.out.println("电气6班和电气7班的人数:" + grade.getCount()); grade.add(class8); System.out.println("电气6班和电气7班和电气8班的人数:" + grade.getCount()); grade.remove(class6); System.out.println("电气7班和电气8班的人数:" + grade.getCount()); System.out.println("电气7班的人数:" + grade.getChild(0).getCount()); System.out.println("电气7班的人数:" + grade.remove(class8).getCount()); } }
电气6班和电气7班的人数:121 电气6班和电气7班和电气8班的人数:191 电气7班和电气8班的人数:138 电气7班的人数:68 电气7班的人数:68
同时组合模式使得向集合添加新类型的组建变得容易,只要这些组建提供一个相似的变成接口即可,但这也是他的缺点,因为这种做法很难限制某个类。