一、概念
组合模式(Composite Pattern):将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
使用场景:组合结构不常用,需要部分与整体的层次关系为树形结构,并且部分与整体的对象是能让客户端能统一对待、不需区分的对象,例如:文件管理系统,在遍历查找的时候,文件和文件夹对我们来说不做区分,可以做到逻辑统一。
二、实现
这里借鉴参考文章公司和职员的例子,公司的组织结构包含部门和员工两种数据类型。其中,部门又可以包含子部门和员工。然后通过构建树形结构来遍历计算公司总的工资支出成本。
1、定义公司及员工的父类HumanResource
,用来统一处理薪资计算。
public abstract class HumanResource {
protected long id;
protected double salary;
public HumanResource(long id) {
this.id = id;
}
public long getId() {
return id;
}
public abstract double calculateSalary();
}
2、员工和部门
#Employee
public class Employee extends HumanResource {
public Employee(long id, double salary) {
super(id); this.salary = salary;
}
@Override
public double calculateSalary() {
return salary;
}
}
#Department
public class Department extends HumanResource {
private List<HumanResource> subNodes = new ArrayList<>();
public Department(long id) {
super(id);
}
@Override
public double calculateSalary() {
double totalSalary = 0;
if (subNodes.size() <= 0) {
return 0;
}
for (HumanResource hr : subNodes) {
totalSalary += hr.calculateSalary();
}
this.salary = totalSalary;
return totalSalary;
}
public void addSubNode(HumanResource hr) {
subNodes.add(hr);
}
}
3、我们建立一个树形部门架构,如下图:
测试类
public class Client {
public static void main(String[] args) {
Department department = new Department(0);
Department departmentA = new Department(1);
Department departmentA1 = new Department(2);
Department departmentB = new Department(3);
Department departmentB1 = new Department(4);
Employee employee0 = new Employee(0,50000);
Employee employee1 = new Employee(1,8000);
Employee employee2 = new Employee(2,8000);
Employee employee3 = new Employee(3,4000);
Employee employee4 = new Employee(4,4000);
department.addSubNode(departmentA);
department.addSubNode(departmentB);
department.addSubNode(employee0);
departmentA.addSubNode(employee1);
departmentA.addSubNode(departmentA1);
departmentB.addSubNode(employee2);
departmentB.addSubNode(departmentB1);
departmentA1.addSubNode(employee3);
departmentB1.addSubNode(employee4);
double salary = department.calculateSalary();
System.out.println("公司工资开支:" + salary);
}
}
4、运行结果
参考文章:
极客时间《设计模式》(王争)