## 1 概述

又称为**部分整体模式**，是用于把一组**相似**的对象当作一个单一的对象。组合模式依据树形结构来组合对象，用来表示部分以及整体层次。属于结构型模式，它创建了对象组的**树形结构**。

组合模式主要包含三种角色：

- 抽象根节点（Component）：定义系统各层次对象的共有方法和属性，可以预先定义一些默认行为和属性。
- 树枝节点（Composite）：定义树枝节点的行为，存储子节点，组合树枝节点和叶子节点形成一个树形结构。
- 叶子节点（Leaf）：叶子节点对象，其下再无分支，是系统层次遍历的最小单位。

分类：

* 透明组合模式：抽象根节点角色中声明了所有用于管理成员对象的方法，add，remove 等。
* 安全组合模式：抽象构件角色中没有声明任何用于管理成员对象的方法。

## 2 例子

一个公司组织架构，有许多员工，员工有上下级关系。

```java
public class Employee {
    private String name;
    private List<Employee> employees;

    public Employee(String name) {
        this.name = name;
        employees = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public void add(Employee employee) {
        employees.add(employee);
    }

    public void remove(Employee employee) {
        employees.remove(employee);
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", employees=" + employees +
                '}';
    }
}

public class TestClient {
    public static void main(String[] args) {
        final Employee a = new Employee("总裁");
        final Employee b1 = new Employee("人事经理");
        final Employee b2 = new Employee("财务经理");

        final Employee c1 = new Employee("人事专员1");
        final Employee c2 = new Employee("人事专员2");


        a.add(b1);
        a.add(b2);

        b1.add(c1);
        b1.add(c2);

        System.out.println(a);
        for (Employee employee : a.getEmployees()) {
            System.out.println(employee);
            for (Employee sub : employee.getEmployees()) {
                System.out.println(sub);
            }
        }
    }
}
```

## 3 优缺点

- 组合模式可以清楚地定义分层次的复杂对象，表示对象的全部或部分层次，它让客户端忽略了层次的差异，方便对整个层次结构进行控制。
- 客户端可以一致地使用一个组合结构或其中单个对象，不必关心处理的是单个对象还是整个组合结构，简化了客户端代码。
- 在组合模式中增加新的树枝节点和叶子节点都很方便，无须对现有类库进行任何修改，符合“开闭原则”。
- 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案，通过叶子节点和树枝节点的递归组合，可以形成复杂的树形结构，但对树形结构的控制却非常简单。