组合
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式(Composite)经常用于树形结构,为了简化代码,使用Composite可以把一个叶子节点与一个父节点统一起来处理。
我们来看一个具体的例子。在XML或HTML中,从根节点开始,每个节点都可能包含任意个其他节点,这些层层嵌套的节点就构成了一颗树。
要以树的结构表示XML,我们可以先抽象出节点类型Node
:
public interface Node {
// 添加一个节点为子节点:
Node add(Node node);
// 获取子节点:
List<Node> children();
// 输出为XML:
String toXml();
}
对于一个<abc>
这样的节点,我们称之为ElementNode
,它可以作为容器包含多个子节点:
public class ElementNode implements Node {
private String name;
private List<Node> list = new ArrayList<>();
public ElementNode(String name) {
this.name = name;
}
public Node add(Node node) {
list.add(node);
return this;
}
public List<Node> children() {
return list;
}
public String toXml() {
String start = "<" + name + ">\n";
String end = "</" + name + ">\n";
StringJoiner sj = new StringJoiner("", start, end);
list.forEach(node -> {
sj.add(node.toXml() + "\n");
});
return sj.toString();
}
}
对于普通文本,我们把它看作TextNode
,它没有子节点:
public class TextNode implements Node {
private String text;
public TextNode(String text) {
this.text = text;
}
public Node add(Node node) {
throw new UnsupportedOperationException();
}
public List<Node> children() {
return List.of();
}
public String toXml() {
return text;
}
}
此外,还可以有注释节点:
public class CommentNode implements Node {
private String text;
public CommentNode(String text) {
this.text = text;
}
public Node add(Node node) {
throw new UnsupportedOperationException();
}
public List<Node> children() {
return List.of();
}
public String toXml() {
return "<!-- " + text + " -->";
}
}
通过ElementNode
、TextNode
和CommentNode
,我们就可以构造出一颗树:
Node root = new ElementNode("school");
root.add(new ElementNode("classA")
.add(new TextNode("Tom"))
.add(new TextNode("Alice")));
root.add(new ElementNode("classB")
.add(new TextNode("Bob"))
.add(new TextNode("Grace"))
.add(new CommentNode("comment...")));
System.out.println(root.toXml());
最后通过root
节点输出的XML如下:
<school>
<classA>
Tom
Alice
</classA>
<classB>
Bob
Grace
<!-- comment... -->
</classB>
</school>
可见,使用Composite模式时,需要先统一单个节点以及“容器”节点的接口:
┌───────────┐
│ Node │
└───────────┘
▲
┌────────────┼────────────┐
│ │ │
┌───────────┐┌───────────┐┌───────────┐
│ElementNode││ TextNode ││CommentNode│
└───────────┘└───────────┘└───────────┘
作为容器节点的ElementNode
又可以添加任意个Node
,这样就可以构成层级结构。
类似的,像文件夹和文件、GUI窗口的各种组件,都符合Composite模式的定义,因为它们的结构天生就是层级结构。
小结
Composite模式使得叶子对象和容器对象具有一致性,从而形成统一的树形结构,并用一致的方式去处理它们。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南