组合模式(Composite Pattern)是一种结构型设计模式,旨在通过将对象组合成树形结构以表示部分-整体的层次结构,使用户对单个对象和组合对象的使用具有一致性。这种模式让客户可以统一地处理单个对象和组合对象。
概念
组合模式主要分为三个角色:
- 组件(Component):是组合中对象声明接口,在适当情况下,实现所有类共有接口的默认行为。用于访问和管理子部件。
- 叶子(Leaf):在组合中表示叶节点对象,叶子节点没有子节点。
- 组合(Composite):定义有枝节点行为,用来存储子部件,在
Component
接口中实现与子部件有关的操作。
优点
- 高层模块调用简单:客户端可以一致的使用组合结构和单个对象。
- 节点自由增加:更容易在组合体内加入对象部件,客户端不会因为加入了新的对象部件而更加复杂。
缺点
- 设计变得更加抽象:设计更加抽象,使得组合的设计变得更加复杂,客户端需要花更多时间理解以便正确地使用。
- 不容易限制组件的类型:很难限制组合中的组件。
Java代码示例
考虑一个简单的文件系统,包含文件和文件夹,文件夹中可以包含文件或其他文件夹。
首先,定义Component
接口:
java复制代码
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public abstract void add(Component c);
public abstract void remove(Component c);
public abstract void display(int depth);
}
实现Leaf
,在这里是File
类:
java复制代码
public class File extends Component {
public File(String name) {
super(name);
}
public void add(Component c) {
System.out.println("Cannot add to a file");
}
public void remove(Component c) {
System.out.println("Cannot remove from a file");
}
public void display(int depth) {
System.out.println(new String("-".repeat(depth)) + name);
}
}
实现Composite
,在这里是Directory
类:
java复制代码
import java.util.ArrayList;
import java.util.List;
public class Directory extends Component {
private List<Component> children = new ArrayList<>();
public Directory(String name) {
super(name);
}
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
public void display(int depth) {
System.out.println(new String("-".repeat(depth)) + name);
for (Component component : children) {
component.display(depth + 2);
}
}
}
使用示例:
java复制代码
public class CompositePatternDemo {
public static void main(String[] args) {
Component rootDirectory = new Directory("root");
Component file1 = new File("File1");
Component file2 = new File("File2");
Component subDirectory = new Directory("subdir");
rootDirectory.add(file1);
rootDirectory.add(subDirectory);
subDirectory.add(file2);
rootDirectory.display(1);
}
}
在这个例子中,Composite
模式允许客户端统一地处理文件和文件夹,客户端无需关心当前操作的是单个文件还是一整个文件夹,大大简化了代码的复杂度。