3.组合模式
概述
处理树形结构或层次结构
业务场景:文件系统管理
假设你正在开发一个文件系统管理工具,文件系统中包含文件夹和文件。
1. 组件接口 (FileSystemComponent
)
public interface FileSystemComponent { void showDetails(); // 显示文件或文件夹的详细信息 long getSize(); // 获取文件或文件夹的大小 }
2. 叶子节点 (File
)
public class File implements FileSystemComponent { private String name; private long size; public File(String name, long size) { this.name = name; this.size = size; } @Override public void showDetails() { System.out.println("文件: " + name + ",大小: " + size + " 字节"); } @Override public long getSize() { return size; } }
3. 组合节点 (Folder
)
import java.util.ArrayList; import java.util.List; public class Folder implements FileSystemComponent { private String name; private List<FileSystemComponent> components = new ArrayList<>(); public Folder(String name) { this.name = name; } public void addComponent(FileSystemComponent component) { components.add(component); } public void removeComponent(FileSystemComponent component) { components.remove(component); } @Override public void showDetails() { System.out.println("文件夹: " + name); for (FileSystemComponent component : components) { component.showDetails(); // 递归显示子组件详情 } } @Override public long getSize() { long totalSize = 0; for (FileSystemComponent component : components) { totalSize += component.getSize(); // 递归计算文件夹大小 } return totalSize; } }
4. 客户端代码
public class FileSystemDemo { public static void main(String[] args) { // 创建文件 FileSystemComponent file1 = new File("file1.txt", 100); FileSystemComponent file2 = new File("file2.txt", 200); FileSystemComponent file3 = new File("file3.txt", 300); // 创建文件夹 Folder folder1 = new Folder("文件夹1"); Folder folder2 = new Folder("文件夹2"); // 将文件添加到文件夹 folder1.addComponent(file1); folder1.addComponent(file2); folder2.addComponent(file3); // 将文件夹添加到另一个文件夹 Folder rootFolder = new Folder("根文件夹"); rootFolder.addComponent(folder1); rootFolder.addComponent(folder2); // 显示文件系统结构 System.out.println("文件系统结构:"); rootFolder.showDetails(); // 计算文件系统总大小 System.out.println("文件系统总大小: " + rootFolder.getSize() + " 字节"); } }
5. 输出
文件系统结构: 文件夹: 根文件夹 文件夹: 文件夹1 文件: file1.txt,大小: 100 字节 文件: file2.txt,大小: 200 字节 文件夹: 文件夹2 文件: file3.txt,大小: 300 字节 文件系统总大小: 600 字节
业务场景总结
-
问题:文件系统中文件夹和文件的操作需要统一处理,但它们的结构是树形的。
-
解决方案:使用组合模式,将文件夹和文件统一抽象为
FileSystemComponent
,使得用户可以一致地处理单个文件和文件夹。 -
优点:
-
统一处理单个对象和组合对象,简化客户端代码。
-
支持递归操作,如计算文件夹大小或显示文件结构。
-
符合开闭原则,易于扩展新的组件类型。
-
其他业务场景
-
组织架构管理:公司中的部门和员工可以组成树形结构,统一管理。
-
菜单系统:菜单和菜单项可以组合成树形结构,支持递归操作。
-
UI 组件:复杂的 UI 界面中,容器组件和叶子组件可以统一管理。
组合模式的核心思想是部分-整体,它通过树形结构统一管理单个对象和组合对象,使得用户可以一致地处理它们。