结构型模式
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 组合模式(Composite Pattern)
- 装饰器模式(Decorator Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
组合模式(Composite Pattern) 是一种结构型设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端可以统一对待单个对象和对象集合,即把对象当作单一对象来处理,从而简化了操作和使用的复杂性。
核心思想:
组合模式将对象组合成树形结构,并允许客户端通过统一的接口对待单一对象和对象组合。其本质是树形结构中的每个节点可能是单个对象,也可能是对象的组合(集合)。客户端通过同一接口处理这些对象,从而达到简化代码和增强灵活性的目的。
主要角色:
- Component(组件):定义了一个接口,声明了基本的操作(如
add()
、remove()
、getChild()
等),这使得单个对象和组合对象(即树枝)都能使用相同的操作。 - Leaf(叶子节点):表示树的叶子节点(即最基本的对象),没有子节点,实现了组件接口。
- Composite(组合节点):表示树的枝节点(即含有子节点的对象),实现了组件接口,并且能管理子组件。组合节点可以添加、删除和获取子组件。
示例:公司组织结构
假设我们有一个公司组织结构,其中有员工(叶子节点)和经理(组合节点),经理可以有下属员工或者其他经理。这种组织结构非常适合使用组合模式来实现。
// 组件接口
public interface Employee {
void showDetails(); // 显示员工信息
}
// 叶子节点,代表普通员工
public class RegularEmployee implements Employee {
private String name;
private String position;
public RegularEmployee(String name, String position) {
this.name = name;
this.position = position;
}
@Override
public void showDetails() {
System.out.println("姓名: " + name + ", 职位: " + position);
}
}
import java.util.ArrayList;
import java.util.List;
// 组合节点,代表经理(可以包含员工或其他经理)
public class Manager implements Employee {
private String name;
private String position;
private List<Employee> subordinates; // 下属
public Manager(String name, String position) {
this.name = name;
this.position = position;
subordinates = new ArrayList<>();
}
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);
System.out.println("下属: ");
for (Employee e : subordinates) {
e.showDetails(); // 递归调用
}
}
}
public class Client {
public static void main(String[] args) {
// 创建叶子节点(普通员工)
Employee employee1 = new RegularEmployee("张三", "开发工程师");
Employee employee2 = new RegularEmployee("李四", "设计师");
// 创建组合节点(经理)
Manager manager1 = new Manager("王五", "经理");
Manager manager2 = new Manager("赵六", "高级经理");
// 经理1有下属员工
manager1.addSubordinate(employee1);
manager1.addSubordinate(employee2);
// 经理2有经理1作为下属
manager2.addSubordinate(manager1);
// 展示组织结构
System.out.println("经理2的详细信息:");
manager2.showDetails();
}
}
解释:
- Employee(组件):定义了一个接口,所有的员工都实现了这个接口,不管是普通员工还是经理。
- RegularEmployee(叶子节点):普通员工,不能有下属,实现了
Employee
接口。 - Manager(组合节点):经理有下属员工或者其他经理。它也实现了
Employee
接口,并且能够管理其他员工(包括普通员工和经理)。
在客户端代码中,Manager
和 RegularEmployee
都通过 Employee
接口处理,使用 showDetails()
方法递归地展示组织结构。无论是单一的普通员工,还是一个包含多个员工和经理的复杂结构,客户端都可以使用相同的接口来处理它们。
装饰器模式 vs 组合模式:
- 装饰器模式:用来动态地向一个对象添加额外的功能,通常涉及一个对象及其装饰器对象的组合。
- 组合模式:用来将对象组织成树形结构,表示“部分-整体”的关系,使得客户端可以统一对待单个对象和对象组合。
优缺点:
优点:
- 透明性:客户端不需要关心对象的组成细节,所有对象(包括单一对象和组合对象)都通过相同的接口进行操作。
- 灵活性:通过递归组合,可以构建出复杂的树形结构,同时提供统一的操作方法。
- 简化代码:对于复杂的层级结构,客户端不需要针对每一层次编写单独的处理代码,减少了重复代码。
缺点:
- 过度设计:如果对象本身没有复杂的层次结构,使用组合模式可能会显得过于复杂。
- 维护困难:在某些场景下,组合模式可能导致代码结构变得非常复杂,特别是当组合对象的层次较深时。
总结:
组合模式通过递归组合的方式,将对象和对象组合统一处理,使得在处理“部分-整体”结构时,客户端代码更加简洁。它适用于具有树形结构的场景,如文件系统、组织结构、菜单结构等。