组合模式是一种结构型设计模式,它允许你将对象组织成树状结构,使得单个对象和组合对象能够以一致的方式被使用。这种模式通过定义一个抽象类或接口,让单个对象和组合对象共享相同的方法,从而使得客户端能够一致地处理它们。
结构
在组合模式中,有三个关键角色:
Component(组件):定义了组合中对象的统一接口,可以是抽象类或接口。它声明了用于管理子对象的方法,包括添加、删除、获取子对象等。
Leaf(叶节点):表示组合中的叶子节点对象,它没有子节点。
Container(容器对象):——又名 “组合 (Composite)“,表示组合中的容器对象,包含叶节点或其他容器。
以文件系统为例,文件和文件夹(目录)可以看作是组合模式的典型实例。文件夹可以包含文件和其他文件夹,形成了一个树形结构,而文件是最终的叶节点。通过组合模式,可以以统一的方式处理文件和文件夹,例如对整个文件系统执行某些操作,无论是对单个文件还是整个文件夹。
代码示例
FileSystemComponent:组件
public interface FileSystemComponent {
void displayInfo();
}
File:叶节点
public class File implements FileSystemComponent {
private String name;
File(String name) {
this.name = name;
}
public void displayInfo() {
System.out.println("This is a file: " + this.name);
}
}
Folder:容器对象
public class Folder implements FileSystemComponent {
private String name;
private List<FileSystemComponent> children;
Folder(String name) {
this.name = name;
this.children = new ArrayList<>();
}
void add(FileSystemComponent component) {
this.children.add(component);
}
void remove(FileSystemComponent component) {
this.children.remove(component);
}
public void displayInfo() {
System.out.println("This is a folder: " + this.name);
for (FileSystemComponent child : this.children) {
child.displayInfo();
}
}
运行示例:
public static void main(String[] args) {
File file1 = new File("file1.txt");
File file2 = new File("file2.txt");
Folder subFolder = new Folder("Subfolder");
subFolder.add(file1);
subFolder.add(file2);
Folder rootFolder = new Folder("Root");
rootFolder.add(subFolder);
rootFolder.add(new File("root_file.txt"));
// Displaying information
rootFolder.displayInfo();
}
优点
- 统一处理:客户端可以一致地处理单个对象和组合对象。
- 灵活性:可以很容易地添加新的组件,扩展性强。
- 简化客户端代码:客户端不需要区分处理单个对象和组合对象。
缺点
- 设计复杂性:可能增加了对象层次结构,引入了更多的抽象和接口。
- 限制类型:由于统一了接口,某些特定操作可能只能在特定类型的组件上执行。
适用场景
- 层次结构对象:当对象可以被组织成树形结构时,可以考虑使用组合模式。
- 统一处理对象集合:当需要以统一的方式处理单个对象和对象组合时,可以使用组合模式。