本文仅供学习交流使用,侵权必删。
不作商业用途,转载请注明出处
WHAT 什么是组合
组合UML.png
组合模式允许你将对象组合成树形结构来表示"整体/部分"的层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
在使用组合结构,我们能把相同的操作应用在组合和个体对象上。大多数情况下,我们能忽略组合和个体的差别。这能简化了我们代码的复杂性。
WHY 为什么使用组合
- 组合模式将个体类和组合类对应的逻辑代码都各自封装符合单一职责原则,代码能变得非常简洁易读。
- 对于高层模块调用更加简单,无需针对个体还是组合做过多的逻辑判断。
组合的缺点
- 业务场景必须能够表示成树形结构,实际开发中适用场景不多。
- 在使用组合模式时,其个体类和组合类的声明都是实现类,而不是接口,违反了依赖倒置原则。
HOW 组合的实现(JAVA)
部门组织架构
上图为部门组织架构图,公司包含部门和员工两种类型,而部门下的子节点可以是部门也可以是员工。我们需要计算每个部门的人员成本,那么其实就是计算每个部门的薪酬总数。我们在设计抽象类时定义一个计算薪酬的抽象方法,然后我们可以通过递归方式将部门的薪酬总数进行汇总。
- 抽象类
public abstract class AbstractResource {
private String id;
public AbstractResource(String id) {
this.id = id;
}
public String getId() {
return id;
}
abstract BigDecimal calculateSalary();
@Override
public String toString() {
return "HumanResource{" +
"id='" + id + '\'' +
'}';
}
}
- 实现类
/*
*员工实现类
*/
public class Employee extends AbstractResource {
private BigDecimal salary;
public Employee(String id, BigDecimal salary) {
super(id);
this.salary = salary;
}
@Override
BigDecimal calculateSalary() {
return salary;
}
public BigDecimal getSalary() {
return salary;
}
}
/*
*部门实现类
*/
public class Department extends AbstractResource {
private BigDecimal salary;
private List<AbstractResource> subNodes = new ArrayList<>();
public Department(String id) {
super(id);
}
@Override
BigDecimal calculateSalary() {
BigDecimal sum = new BigDecimal("0");
for (AbstractResource n : subNodes) {
sum = sum.add(n.calculateSalary());
}
salary = sum;
return salary;
}
public BigDecimal getSalary() {
return salary;
}
public void addNode(AbstractResource hr) {
if (hr == null) {
return;
}
if (hr.getId().equalsIgnoreCase(getId())) {
return;
}
if (!subNodes.contains(hr)) {
subNodes.add(hr);
}
}
public void removeNode(AbstractResource hr) {
if (hr == null) {
return;
}
removeNode(hr.getId());
}
public void removeNode(String id) {
if (id.isEmpty() || id == null) {
return;
}
for (int i = 0; i < subNodes.size(); i++) {
if (subNodes.get(i).getId().equalsIgnoreCase(id)) {
subNodes.remove(i);
break;
}
}
}
}
- Main方法
public class CompositeSalaryMain {
public static void main(String[] args) {
//总公司
Department headOffice = new Department("000");
//财务部
Department finance = new Department("0001");
//信息科技部
Department it = new Department("0002");
//运营部
Department operation = new Department("0003");
//开发部
Department develop = new Department("00021");
//测试部
Department test = new Department("00022");
Employee financeEmployee1 = new Employee("0001-1", new BigDecimal("1000"));
Employee financeEmployee2 = new Employee("0001-2", new BigDecimal("1000"));
Employee developEmployee1 = new Employee("00021-1", new BigDecimal("1500"));
Employee developEmployee2 = new Employee("00021-2", new BigDecimal("1500"));
Employee testEmployee1 = new Employee("00022-1", new BigDecimal("2000"));
Employee operationEmployee1 = new Employee("0003-1", new BigDecimal("1500"));
headOffice.addNode(finance);
headOffice.addNode(it);
headOffice.addNode(operation);
finance.addNode(financeEmployee1);
finance.addNode(financeEmployee2);
it.addNode(develop);
it.addNode(test);
test.addNode(testEmployee1);
develop.addNode(developEmployee1);
develop.addNode(developEmployee2);
operation.addNode(operationEmployee1);
BigDecimal sum = headOffice.calculateSalary();
System.out.println(sum);
}
}