23种设计模式之组合设计模式
文章目录
- 1. 简介
- 2. 代码
- 2.1 Employee (三合一)
- 2.2 Test
- 2.3 其他例子
- 3. 使用场景
- 4. 优缺点
- 5. 总结
1. 简介
组合设计模式(Composite Pattern)是一种结构型设计模式。它允许你将对象组合成树形结构来表示 “部分 - 整体” 的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性,即可以像操作单个对象一样操作组合对象。
- 结构组成
- 组件(Component)接口或抽象类 :这是组合模式中的最顶层抽象,它定义了叶子节点和组合节点(包含其他子节点的节点)的公共操作接口。例如,在一个文件系统的模拟中,这个接口可能包含诸如getName()(获取名称)、getSize()(获取大小)等方法。
- 叶子节点(Leaf):叶子节点是树形结构中的最底层对象,它没有子节点。它们实现了组件接口,但因为没有子节点,所以对于组合相关的操作(如添加或删除子节点)没有实际意义。例如,在文件系统中,文件就是叶子节点,它有自己的名称和大小,但不能包含其他文件或文件夹。
- 组合节点(Composite):组合节点是包含子节点的节点,它也实现了组件接口。它内部维护了一个子节点的集合,并且实现了添加、删除和获取子节点等操作。在文件系统示例中,文件夹就是组合节点,它可以包含文件和其他文件夹。
2. 代码
2.1 Employee (三合一)
import java.util.ArrayList;
import java.util.List;
public class Employee {
private String name;
private String position;
private int salary;
private List<Employee> employees;
public Employee(String name, String position, int salary) {
this.name = name;
this.position = position;
this.salary = salary;
employees = new ArrayList<>();
}
public void addEmployee(Employee employee) {
employees.add(employee);
}
public void removeEmployee(Employee employee) {
employees.remove(employee);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", position='" + position + '\'' +
", salary=" + salary +
'}';
}
}
2.2 Test
public class Test {
public static void main(String[] args) {
// CEO
Employee ceo = new Employee("dev1", "ceo", 10000);
// 部门经理
Employee manager = new Employee("dev2", "manager", 5000);
// 创建销售员
Employee saller1 = new Employee("dev3", "saller1", 4000);
Employee saller2 = new Employee("dev3", "saller2", 4000);
// 仓库管理员
Employee warehouse = new Employee("dev4", "warehouse", 3000);
ceo.addEmployee(manager);
manager.addEmployee(saller1);
manager.addEmployee(saller2);
manager.addEmployee(warehouse);
System.out.println(ceo);
for(Employee employee : ceo.getEmployees()){
System.out.println(employee);
for(Employee e : employee.getEmployees()){
System.out.println(e);
}
}
}
}
输出结果:
Employee{name='dev1', position='ceo', salary=10000}
Employee{name='dev2', position='manager', salary=5000}
Employee{name='dev3', position='saller1', salary=4000}
Employee{name='dev3', position='saller2', salary=4000}
Employee{name='dev4', position='warehouse', salary=3000}
2.3 其他例子
// 组件接口
interface FileSystemComponent {
String getName();
long getSize();
}
// 叶子节点 - 文件
class File implements FileSystemComponent {
private String name;
private long size;
public File(String name, long size) {
this.name = name;
this.size = size;
}
@Override
public String getName() {
return name;
}
@Override
public long getSize() {
return size;
}
}
// 组合节点 - 文件夹
class Directory implements FileSystemComponent {
private String name;
private java.util.ArrayList<FileSystemComponent> children = new java.util.ArrayList<>();
public Directory(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public long getSize() {
long size = 0;
for (FileSystemComponent child : children) {
size += child.getSize();
}
return size;
}
public void add(FileSystemComponent component) {
children.add(component);
}
public void remove(FileSystemComponent component) {
children.remove(component);
}
public FileSystemComponent[] getChildren() {
return children.toArray(new FileSystemComponent[0]);
}
}
3. 使用场景
- 树形结构数据表示:组合模式非常适合用于表示具有层次结构的数据,如文件系统、组织结构图、菜单系统等。例如,在一个公司的组织结构中,部门可以包含子部门和员工,使用组合模式可以方便地对整个组织结构进行操作,如计算部门的总人数、获取部门的所有下属等。
- 统一处理对象和对象集合:当需要以相同的方式处理单个对象和对象集合时,组合模式是很好的选择。比如在图形绘制系统中,图形可以是单个的点、线,也可以是由多个图形组成的复杂图形。通过组合模式,可以统一地对这些图形进行绘制、移动、缩放等操作。
4. 优缺点
- 优点
- 层次结构清晰:组合模式能够清晰地表示出对象之间的层次关系,使得代码结构更加直观,易于理解和维护。
- 客户端调用简单:客户端可以统一地使用组件接口来操作单个对象和组合对象,不需要分别处理不同类型的对象,降低了客户端代码的复杂性。
- 可扩展性强:可以方便地添加新的叶子节点或组合节点类型,只要它们实现了组件接口,就可以融入到现有的层次结构中。
- 缺点
- 设计复杂度过高:对于简单的层次结构,使用组合模式可能会使设计变得过于复杂,增加了代码的理解和实现成本。
- 限制了叶子节点和组合节点的差异性:由于叶子节点和组合节点都要实现组件接口,可能会导致一些不符合实际情况的接口实现。例如,叶子节点可能不需要实现与子节点相关的操作,但为了符合接口要求,也需要提供这些操作的空实现。
5. 总结
无,哈哈