概念:
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
组合模式主要角色:
抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性
树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点行成一个树形结构
叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位
实现案例:
这里以一个公司的组织架构为例,利用组合模式表示出公司人员部门信息。(OrgComponent)抽象根节点角色,封装了默认属性和方法;(Group)树枝节点角色,实现了抽象节点,并实现了相关方法;(Person)叶子节点角色,用于表示某个人员。
//抽象根节点角色 (表示默认行为和属性)
public abstract class OrgComponent {
//名称
protected String name;
//等级
protected int grade;
//添加
public void add(OrgComponent component) {
}
//移除
public void remove(OrgComponent component) {
}
//获取名称
public String getName() {
return name;
}
//打印组织信息
public abstract void print();
}
//树枝节点角色 (表示部门信息)
public class Group extends OrgComponent {
private List<OrgComponent> list = new ArrayList<>();
public Group(String name, int grade) {
this.name = name;
this.grade = grade;
}
@Override
public void add(OrgComponent component) {
list.add(component);
}
@Override
public void remove(OrgComponent component) {
list.remove(component);
}
@Override
public void print() {
for (int i = 0; i < grade; i++) {
System.out.print(">>");
}
System.out.println("部门:" + name);
for (OrgComponent component : list) {
component.print();
}
}
}
//叶子节点(表示人员)
public class Person extends OrgComponent {
public Person(String name, int grade) {
this.name = name;
this.grade = grade;
}
@Override
public void print() {
for (int i = 0; i < grade; i++) {
System.out.print(">>");
}
System.out.println("人员: "+name);
}
}
public class Test {
public static void main(String[] args) {
OrgComponent org1 = new Group("人事部", 1);
org1.add(new Person("人事张三", 2));
org1.add(new Person("人事李四", 2));
org1.add(new Person("人事王五", 2));
OrgComponent org2 = new Group("开发部", 1);
org2.add(new Person("开发总监", 2));
OrgComponent java = new Group("Java组", 2);
java.add(new Person("java张三", 3));
java.add(new Person("java李四", 3));
java.add(new Person("java王五", 3));
org2.add(java);
OrgComponent android = new Group("Android组", 2);
android.add(new Person("android张三", 3));
org2.add(android);
OrgComponent org = new Group("某科技公司", 0);
org.add(org1);
org.add(org2);
org.print();
}
}
执行结果:
组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,对树形结构的控制却非常简单。当需要增加人员信息或者部门信息时,不需要对现有代码有任何修改,只需要增加相关类信息即可。
组合模式分类:
透明组合模式和安全组合模式两种
透明组合模式是组合模式的标准实现方式;其中抽象根节点角色中声明了所有用于管理成员对象的方法,(比如在案例中 OrgComponent声明 add remove 等方法)。
优点:确保所有的构件都有相同的接口,不需要区分到底是部门还是人员
缺点:不够安全,叶子对象和容器对象本质上是有区别的,叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供的add、remove方法没有意义,可能会调用出错情况
安全组合模式在抽象构件角色中没有声明任何用于管理成员对象的方法,而是在树枝节点 Group类中声明并实现这些方法。
缺点:不够透明,叶子构件和容器构件具有不同的方法,且容器构件中用于管理成员对象的方法没有在抽象构件类中定义,因为不能做到完全针对抽象编程,需要有区别的对待叶子和容器构件
组合模式优缺点:
优点:
1、高层模块调用简单
2、节点自由增加
缺点:
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
使用场景:
组合模式应树形结构而生,对出现树形结构的地方都可以使用,比如文件目录、菜单、组织架构等