# 组合模式
# 概念
组合模式(Composite Pattern)是一种结构型设计模式,它将对象组合成树形结构以表示"部分-整体"的层次结构。该模式允许用户以统一的方式处理单个对象和组合对象,简化了客户端代码并增强了系统的灵活性。
# 作用
1.统一处理方式:用户可以用相同的方式处理单个对象和组合对象,无需区分。
2.简化客户端代码:客户端只需与顶层组件交互,无需关心内部复杂结构。
3.灵活构建层次结构:可以动态添加或删除组件,构建复杂的树形结构。
4.增强扩展性:新增组件类型时无需修改现有代码,符合开闭原则。
# 场景
1.表示对象的部分-整体层次结构:如文件系统(文件/文件夹)、组织架构(员工/部门)。
2.需要统一处理简单元素和复杂元素:如GUI组件(按钮/面板)、菜单系统。
3.处理树形数据结构:如XML/JSON解析、目录树展示。
4.需要递归组合的场景:如数学表达式(操作数/运算符)。
# 举例
以下是使用组合模式实现公司员工层级关系的Java代码示例:
// 组件接口(Component),所有对象(树枝和叶子)都实现这个接口
interface EmployeeComponent {
void add(EmployeeComponent employee);
void remove(EmployeeComponent employee);
void display();
}
// 叶子节点(Leaf)
class Employee implements EmployeeComponent {
private String name;
private String position;
public Employee(String name, String position) {
this.name = name;
this.position = position;
}
// 因为叶子节点不能添加子节点,所以这里要报错
@Override
public void add(EmployeeComponent employee) {
throw new UnsupportedOperationException("Cannot add to a leaf node.");
}
// 同上
@Override
public void remove(EmployeeComponent employee) {
throw new UnsupportedOperationException("Cannot remove from a leaf node.");
}
@Override
public void display() {
System.out.println("Employee: " + name + " (" + position + ")");
}
}
// 容器节点(Composite)
class Department implements EmployeeComponent {
private String name;
private List<EmployeeComponent> employees = new ArrayList<>();
public Department(String name) {
this.name = name;
}
@Override
public void add(EmployeeComponent employee) {
employees.add(employee);
}
@Override
public void remove(EmployeeComponent employee) {
employees.remove(employee);
}
@Override
public void display() {
System.out.println("Department: " + name);
for (EmployeeComponent employee : employees) {
employee.display();
}
}
}
控制台输出:
// 客户端代码
public class Main {
public static void main(String[] args) {
Department hrDepartment = new Department("Human Resources");
hrDepartment.add(new Employee("Alice", "HR Manager"));
hrDepartment.add(new Employee("Bob", "Recruiter"));
Department itDepartment = new Department("Information Technology");
itDepartment.add(new Employee("Charlie", "IT Manager"));
itDepartment.add(new Employee("Diana", "Software Engineer"));
Department company = new Department("Company");
company.add(hrDepartment);
company.add(itDepartment);
company.display();
}
}
# 反例
如果不使用组合模式,我们需要为单个员工和部门分别处理,导致代码重复且难以维护整体结构:
class Employee {
private String name;
private String position;
public Employee(String name, String position) {
this.name = name;
this.position = position;
}
public void display() {
System.out.println("Employee: " + name + " (" + position + ")");
}
}
class Department {
private String name;
private List<Employee> employees = new ArrayList<>();
public Department(String name) {
this.name = name;
}
public void addEmployee(Employee employee) {
employees.add(employee);
}
public void removeEmployee(Employee employee) {
employees.remove(employee);
}
public void display() {
System.out.println("Department: " + name);
for (Employee employee : employees) {
employee.display();
}
}
}
public class Main {
public static void main(String[] args) {
Employee alice = new Employee("Alice", "HR Manager");
Employee bob = new Employee("Bob", "Recruiter");
Department hrDepartment = new Department("Human Resources");
hrDepartment.addEmployee(alice);
hrDepartment.addEmployee(bob);
Employee charlie = new Employee("Charlie", "IT Manager");
Employee diana = new Employee("Diana", "Software Engineer");
Department itDepartment = new Department("Information Technology");
itDepartment.addEmployee(charlie);
itDepartment.addEmployee(diana);
System.out.println("HR Department:");
hrDepartment.display();
System.out.println("\nIT Department:");
itDepartment.display();
}
}
# 原理
组合模式包含四个核心组成部分:
1.组件(Component):定义组合中所有对象的通用接口,声明用于访问和管理子组件的方法(如add/remove/display)。可以是接口或抽象类。
2.叶子节点(Leaf):表示组合中的基本元素(如员工),没有子节点。实现组件接口的操作方法,但子组件管理方法需抛出异常或空实现。
3.容器节点(Composite):表示包含子组件的复合元素(如部门)。实现组件接口的所有方法,内部维护子组件集合,并将操作委托给子组件。
4.客户端(Client):通过组件接口与组合结构交互,无需区分叶子节点和容器节点,统一处理所有组件。
# 特点
# 优点
1.可以方便地将对象组合成树形结构,表示"部分-整体"的层次关系。
2.单个对象和组合对象具有相同的接口,用户可以以统一的方式处理它们。
3.增加新的组件类变得容易。
# 缺点
1.可能会导致设计中出现过多的抽象类或接口,从而增加系统的复杂性。
2.可能会使得系统的行为变得难以预测,因为用户可以以任何方式组合对象。
总结
组合模式通过树形结构统一处理单个对象与组合对象,简化了客户端代码并增强了系统扩展性。它适用于表示部分-整体层次结构,如组织架构、文件系统等场景,但需注意避免过度设计带来的复杂性。

微信公众号

QQ交流群
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。