一、组合模式的定义
组合模式(Composite Pattern)是一种结构型设计模式,它让我们可以将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式允许客户端以统一的方式对待单个对象和对象集合。它适用于表示具有层次关系的对象结构。
组合模式允许你将多个对象(无论是单个对象还是对象集合)组合成一个树形结构,以便客户端可以像操作单一对象一样操作整个对象树。它使得客户端在处理对象的集合时不需要关心集合中的元素类型,统一通过相同的接口进行操作。
二、组合模式的组成
-
Component(组件):这是一个抽象类或接口,定义了叶子对象和组合对象的共同行为。所有的对象(无论是叶子节点还是组合节点)都应该实现该接口。
-
Leaf(叶子节点):在组合结构中,叶子节点表示树的最底层节点,它没有子节点。通常是一些基本的操作。
-
Composite(组合节点):它定义了具有子节点的对象,作为容器来存放叶子节点或者其他组合节点。它实现了
Component
接口,并且能够管理和操作其子节点。 -
Client(客户端):客户端通过调用
Component
接口来操作树形结构,无论是操作单一对象还是操作对象集合。
三、组合模式的优点
-
透明性:客户端不需要关心对象是叶子节点还是组合节点,客户端代码通过
Component
接口来操作所有对象。 -
递归结构:组合模式能够自然地表示递归结构,比如文件系统、组织结构等。
-
简化代码:通过组合多个对象,可以减少客户端代码的复杂度,避免了大量条件判断。
四、组合模式的缺点
-
设计复杂:组合模式可能会引入过多的子类和接口,从而使得系统变得复杂。尤其是如果不需要层次结构时,引入组合模式可能是过度设计。
-
过度泛化:由于所有对象(无论是叶子节点还是组合节点)都通过相同的接口进行操作,可能会出现不必要的泛化,导致某些行为变得不够直观或不合理。
五、组合模式的实现示例
1.业务场景
假设我们有一个公司,员工分为普通员工和经理。经理有下属员工,并且经理的薪资包含了下属员工的薪资。经理也可以是其他经理的下属,因此形成了树形结构。我们要实现一个组合模式,其中 Worker
(普通员工)和 Manager
(经理)是两种角色,而 Manager
可以拥有多个 Worker
和其他 Manager
。
2.角色说明
Employee
:员工接口,定义了所有员工的基本操作,例如显示信息和计算薪资。Worker
:普通员工类,属于叶子节点,没有下属。Manager
:经理类,属于组合节点,可以有多个下属(其他员工或经理)。
3.代码实现
// Employee 接口,表示员工的基本操作
public interface Employee {
void showDetails(); // 显示员工信息
double getSalary(); // 获取员工薪资
}
// Worker 类,表示普通员工
public class Worker implements Employee {
private String name;
private String position;
private double salary;
public Worker(String name, String position, double salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
@Override
public void showDetails() {
System.out.println("员工姓名:" + name + ", 职位:" + position + ", 薪资:" + salary);
}
@Override
public double getSalary() {
return salary;
}
}
// Manager 类,表示经理,负责管理下属
public class Manager implements Employee {
private String name;
private String position;
private double salary;
private List<Employee> subordinates = new ArrayList<>(); // 存储下属员工
public Manager(String name, String position, double salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
// 添加下属
public void addSubordinate(Employee employee) {
subordinates.add(employee);
}
// 移除下属
public void removeSubordinate(Employee employee) {
subordinates.remove(employee);
}
@Override
public void showDetails() {
System.out.println("经理姓名:" + name + ", 职位:" + position + ", 薪资:" + salary);
System.out.println("下属:");
for (Employee subordinate : subordinates) {
subordinate.showDetails();
}
}
@Override
public double getSalary() {
double totalSalary = salary;
for (Employee subordinate : subordinates) {
totalSalary += subordinate.getSalary(); // 累加下属的薪资
}
return totalSalary;
}
}
4.代码解析
-
Employee 接口:所有员工都实现了这个接口,包含了
showDetails()
和getSalary()
方法,提供了展示员工信息和计算薪资的功能。 -
Worker 类:普通员工类实现了
Employee
接口,表示树的叶子节点,没有下属,只能提供自身的薪资和信息。 -
Manager 类:经理类实现了
Employee
接口,表示树的组合节点,能够包含下属员工。它有addSubordinate()
和removeSubordinate()
方法来添加和移除下属。它会遍历所有下属来计算总薪资。
5.测试类
public class TestComponent {
public static void main(String[] args) {
// 下属员工信息
Employee employee1 = new Worker("Theodore", "软件设计师", 12000);
Employee employee2 = new Worker("Andy", "网络工程师", 10000);
// 经理信息
Manager manager = new Manager("小胖", "研发部经理", 15000);
// 添加经理下属
manager.addSubordinate(employee1);
manager.addSubordinate(employee2);
// 显示经理及其下属员工的详细信息
System.out.println("经理及其下属信息:");
manager.showDetails();
// 计算并显示经理的薪资总额(包括下属的薪资)
System.out.println("经理总薪资:" + manager.getSalary());
// 创建一个更高级的经理并添加其下属(包括之前的经理)
Manager seniorManager = new Manager("大胖", "CEO", 20000);
seniorManager.addSubordinate(manager);
// 显示高级经理及其下属(包括原经理)的信息
System.out.println("\n高级经理及其下属信息:");
seniorManager.showDetails();
// 计算并显示高级经理的薪资总额(包括下属的薪资)
System.out.println("高级经理总薪资:" + seniorManager.getSalary());
}
}
6.输出示例
经理及其下属信息:
经理姓名:小胖, 职位:研发部经理, 薪资:15000.0
下属:
员工姓名:Theodore, 职位:软件设计师, 薪资:12000.0
员工姓名:Andy, 职位:网络工程师, 薪资:10000.0
经理总薪资:37000.0高级经理及其下属信息:
经理姓名:大胖, 职位:CEO, 薪资:20000.0
下属:
经理姓名:小胖, 职位:研发部经理, 薪资:15000.0
下属:
员工姓名:Theodore, 职位:软件设计师, 薪资:12000.0
员工姓名:Andy, 职位:网络工程师, 薪资:10000.0
高级经理总薪资:59000.0
六、总结
组合模式通过允许将单个对象和对象集合统一处理,使得客户端代码可以以一致的方式对待组合对象和单一对象。这个模式非常适合那些需要表示部分-整体层次结构的场景,如组织结构、文件系统等。在本示例中,Worker
作为叶子节点,Manager
作为组合节点,它们通过实现共同的 Employee
接口,实现了层次结构中的统一操作。
组合模式使得复杂的树形结构能够轻松地进行管理,同时减少了客户端代码的复杂性。
标签:公司员工,17,经理,节点,Employee,组合,薪资,设计模式,下属 From: https://blog.csdn.net/Theodore_1022/article/details/144298004