组合模式适合企业组织架构等树形结构,通过统一接口OrgUnit使“查人数”“拉名单”等操作无需判断节点类型,叶子节点(Employee)和容器节点(Department)分别实现简单返回与递归聚合,客户端代码简洁稳定且易扩展。

组合模式特别适合管理企业组织架构这类天然具备“部分-整体”树形结构的场景。它的核心价值不是多写几个类,而是让“查人数”“算薪资”“发通知”这类操作不再需要一层层判断是部门还是员工——统一调用一个方法,自动递归到底。
明确组织节点的两种角色
企业架构里,节点只有两类:
- 叶子节点:具体员工(无下属)
- 容器节点:部门或团队(有下属,下属可以是员工,也可以是其他部门)
两者对外暴露相同能力(比如“获取总人数”“列出所有成员”),但内部实现不同。
定义统一接口,聚焦业务行为
不叫 Component 或 Node 这类泛称,直接按业务命名,例如:
public interface OrgUnit {
String getName(); // 所有单位都有名称
int getTotalStaffCount(); // 统一统计人数(关键!)
List<String> getAllNames(); // 统一拉取全部人员姓名
}这个接口只包含业务语义明确的方法,不塞 add()、remove() 等管理操作——那是容器自己的事,叶子不该也不需实现。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
叶子节点(员工)直接返回自身信息
public class Employee implements OrgUnit {
private final String name;
private final int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
@Override
public String getName() { return name; }
@Override
public int getTotalStaffCount() { return 1; } // 员工就是1人
@Override
public List<String> getAllNames() { return List.of(name); }
}容器节点(部门)聚合并递归委托
public class Department implements OrgUnit {
private final String name;
private final List<OrgUnit> subUnits = new ArrayList<>();
public Department(String name) {
this.name = name;
}
public void add(OrgUnit unit) {
subUnits.add(unit);
}
@Override
public String getName() { return name; }
@Override
public int getTotalStaffCount() {
return subUnits.stream()
.mapToInt(OrgUnit::getTotalStaffCount)
.sum();
}
@Override
public List<String> getAllNames() {
return subUnits.stream()
.flatMap(unit -> unit.getAllNames().stream())
.toList();
}
}客户端代码变得极简且稳定
Department hrDept = new Department("人力资源部");
hrDept.add(new Employee("张三", 15000));
hrDept.add(new Employee("李四", 14500));
Department techDept = new Department("技术中心");
techDept.add(new Employee("王五", 22000));
techDept.add(new Employee("赵六", 21000));
Department company = new Department("总公司");
company.add(hrDept);
company.add(techDept);
System.out.println("总人数:" + company.getTotalStaffCount()); // 输出:4
System.out.println("全员名单:" + company.getAllNames()); // 输出:[张三, 李四, 王五, 赵六]新增“子公司”或“项目组”这类新类型?只需让它实现 OrgUnit 接口,现有统计逻辑完全不用改。
注意两个实际细节
- 避免在
Employee里空实现add()—— 这属于安全式组合,把管理方法只放在Department中,防止误调用 - 如果架构存在循环引用(比如A部门隶属B,B又隶属A),递归前加简单路径检测,避免栈溢出
本质上,组合模式在这里不是为“设计而设计”,而是把组织树的天然递归性,原样映射到代码结构中,让业务逻辑干净、可读、可扩。

















