Composite 模式

  • ~3.42K 字
  1. 1. Composite 模式
    1. 1.1. 一、基础介绍
    2. 1.2. 二、生活比喻:文件系统
    3. 1.3. 三、应用场景
    4. 1.4. 四、使用注意事项
      1. 1.4.1. 优点
      2. 1.4.2. 缺点
    5. 1.5. 五、Java 经典案例
      1. 1.5.1. 文件系统
    6. 1.6. 六、Python 经典案例
      1. 1.6.1. 图形绘制系统
    7. 1.7. 七、参考资料与延伸阅读
      1. 1.7.1. 相关设计模式

Composite 模式

一、基础介绍

Composite(组合)模式是一种结构型设计模式,它将对象组合成树形结构来表示”部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性。

二、生活比喻:文件系统

想象一个计算机文件系统

传统方式:文件和文件夹需要分别处理。列出内容、计算大小、删除等操作,两者处理方式不同。

组合方式:文件和文件夹都实现了相同的接口。对文件或文件夹调用 getSize(),文件夹会递归计算所有子项的大小。

三、应用场景

场景 说明 示例
树形结构 需要表示部分-整体层次结构 文件系统、组织架构
统一处理 希望一致对待单个和组合对象 菜单系统、GUI组件
递归遍历 需要对树形结构递归操作 DOM树、语法树

四、使用注意事项

优点

优点 说明
统一接口 客户端一致对待单个和组合对象
层次清晰 树形结构直观表达层次关系
扩展灵活 可方便增加新的节点类型

缺点

缺点 说明
设计复杂 较难限制组合中的组件类型
类型安全 运行时才能发现类型错误

五、Java 经典案例

文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.util.ArrayList;
import java.util.List;

// 抽象组件
abstract class Entry {
protected String name;
public Entry(String name) { this.name = name; }
public abstract int getSize();
public abstract void print();
}

// 叶子节点:文件
class File extends Entry {
private int size;
public File(String name, int size) {
super(name);
this.size = size;
}
public int getSize() { return size; }
public void print() {
System.out.println(name + " (" + size + " KB)");
}
}

// 组合节点:目录
class Directory extends Entry {
private List<Entry> entries = new ArrayList<>();
public Directory(String name) { super(name); }
public void add(Entry entry) { entries.add(entry); }
public int getSize() {
int size = 0;
for (Entry entry : entries) {
size += entry.getSize();
}
return size;
}
public void print() {
System.out.println(name + " (" + getSize() + " KB)");
for (Entry entry : entries) {
entry.print();
}
}
}

// 使用
public class CompositeDemo {
public static void main(String[] args) {
Directory root = new Directory("root");
Directory home = new Directory("home");
File file1 = new File("readme.txt", 10);
File file2 = new File("doc.pdf", 500);

root.add(home);
home.add(file1);
root.add(file2);

root.print();
}
}

六、Python 经典案例

图形绘制系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from abc import ABC, abstractmethod
from typing import List


class Graphic(ABC):
@abstractmethod
def draw(self) -> None: pass


class Circle(Graphic):
def __init__(self, name: str, radius: float):
self.name = name
self.radius = radius

def draw(self) -> None:
print(f"绘制圆形: {self.name}")


class Picture(Graphic):
def __init__(self, name: str):
self.name = name
self.graphics: List[Graphic] = []

def add(self, graphic: Graphic) -> None:
self.graphics.append(graphic)

def draw(self) -> None:
print(f"绘制图片: {self.name}")
for g in self.graphics:
g.draw()


# 使用
def main():
circle1 = Circle("圆1", 10)
circle2 = Circle("圆2", 15)

picture = Picture("组合图")
picture.add(circle1)
picture.add(circle2)

picture.draw()


if __name__ == "__main__":
main()

七、参考资料与延伸阅读

相关设计模式

  • Decorator:Decorator 为对象添加功能,Composite 构建层次结构
  • Iterator:常用于遍历 Composite 结构
  • Visitor:可以对 Composite 结构执行复杂操作
打赏
打赏提示信息