组合模式(Composite Pattern)是 GoF 提出的结构型设计模式之一,核心思想是:用一致的方式处理“单个对象”和“对象集合”,让客户端无需关心操作的是叶子节点还是容器节点。
下面从「是什么 → 为什么用 → 怎么写 → 实际例子 → 常见误区」来理解 Java 中的组合模式。
定义:
将对象组合成树形结构,以表示“部分—整体”的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性。
一句话理解:
不管是“一个文件”还是“一个文件夹”,你都能用同样的方法去“打开 / 删除 / 打印”。
if (obj instanceof Folder) {
for (File f : folder.getFiles()) {
f.print();
}
} else {
obj.print();
}
客户端必须:
component.print();
无论它是:
调用方式完全一样。
定义所有对象的公共接口
public abstract class Component {
public abstract void operation();
}
没有子节点
public class Leaf extends Component {
@Override
public void operation() {
System.out.println("叶子节点操作");
}
}
包含子组件
import java.util.ArrayList;
import java.util.List;
public class Composite extends Component {
private List<Component> children = new ArrayList<>();
public void add(Component c) {
children.add(c);
}
public void remove(Component c) {
children.remove(c);
}
@Override
public void operation() {
System.out.println("容器节点操作");
for (Component c : children) {
c.operation();
}
}
}
public class Client {
public static void main(String[] args) {
Composite root = new Composite();
root.add(new Leaf());
root.add(new Leaf());
Composite sub = new Composite();
sub.add(new Leaf());
root.add(sub);
root.operation();
}
}
✅ 客户端不关心层级和类型
Directory
├── File
├── File
└── Directory
├── File
└── File
所有方法都放在 Component 中
public abstract class Component {
public abstract void operation();
public void add(Component c) {}
public void remove(Component c) {}
}
优点:客户端完全统一
缺点:Leaf 中可能有无意义的方法
只在 Composite 中定义 add / remove
public class Leaf extends Component {
// 没有 add / remove
}
优点:更安全
缺点:客户端需要类型判断
✅ 适用:
❌ 不适用:
Component → ContainerList, Set 嵌套使用BeanDefinitionCompositeFilter组合模式让“单个对象”和“对象组合”长得一样、用得一样,从而用树形结构优雅地处理递归关系。
如果你愿意,我可以用菜单系统 / 公司组织架构 / UI 组件树给你写一个更直观的 Java 示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。