组合模式
# 组合模式
# 定义
组合模式是一种结构型设计模式,它允许将对象组织成树状结构,并以统一的方式处理组合对象和叶子对象。该模式通过将对象组织成层次结构,使得客户端可以一致地处理单个对象和对象的集合。
# 结构
抽象接口(Component):它的主要作用是为树枝节点和叶子节点声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象接口还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝节点完成。
树枝节点(Composite):代表树状结构中的节点。组合对象可以包含其他组合对象或叶子对象,并实现与其子对象相关的操作。
叶子节点(Leaf):代表树状结构中的叶子节点。叶子构件是最基本的单位,它没有子对象,并实现了与其父对象相同的操作。
- img: https://bitouyun.com/images/design-pattern/composite.png
link: https://bitouyun.com/images/design-pattern/composite.png
name: 组合模式-透明模式
- img: https://bitouyun.com/images/design-pattern/composite2.png
link: https://bitouyun.com/images/design-pattern/composite2.png
name: 组合模式-安全模式
1
2
3
4
5
6
2
3
4
5
6
# 优点
组合模式通过将对象组织成树状结构,提供了一种灵活且统一的方式来处理树枝节点和叶子节点。它简化了客户端代码,提高了代码的可读性和可维护性,同时具有灵活性、扩展性和统一的处理方式。这使得组合模式成为处理树状结构的一种强大工具。
# 缺点
组合模式引入了组合对象和叶子对象之间的层次结构,这增加了系统的设计复杂性。由于组合模式中可能存在大量的递归操作,对于非常庞大的树状结构,可能会导致性能问题。
# 应用场景
组合模式适用于需要处理树状结构、统一操作接口、递归操作以及动态组合的场景。通过使用组合模式,可以简化代码、提高灵活性,并实现代码的重用性。
# 示例代码1
场景1
透明模式,树枝节点和叶子节点具有相同的接口,客户端调用简单。
/**
* 抽象接口
* 透明模式
*/
public interface Component {
// 添加节点(默认实现)
default void add(Component component) {
throw new UnsupportedOperationException();
}
// 删除节点(默认实现)
default void remove(Component component) {
throw new UnsupportedOperationException();
}
// 显示节点
void display(int depth);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 树枝节点
*/
public class Composite implements Component {
// 节点名称
private String name;
public Composite(String name) {
this.name = name;
}
private List<Component> children = new ArrayList<>();
@Override
public void add(Component component) {
children.add(component);
}
@Override
public void remove(Component component) {
children.remove(component);
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
// 遍历下级
children.forEach(c -> c.display(depth + 1));
}
}
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
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
/**
* 叶子节点
*/
public class Leaf implements Component {
// 节点名称
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 测试类
* 透明模式,树枝节点和叶子节点具有相同的接口,客户端调用简单。
*/
public class Client {
public static void main(String[] args) {
// 树枝构件
Composite user = new Composite("用户管理");
Composite role = new Composite("角色管理");
Composite menu = new Composite("菜单管理");
// 抽象构件
Composite system = new Composite("系统管理");
system.add(user);
system.add(role);
system.add(menu);
// 叶子构件
Leaf addUser = new Leaf("添加用户");
Leaf editUser = new Leaf("编辑用户");
Leaf removeUser = new Leaf("删除用户");
user.add(addUser);
user.add(editUser);
user.add(removeUser);
system.display(1);
}
}
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
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
// Make sure to add code blocks to your code group
# 示例代码2
场景2
安全模式,树枝节点和叶子节点分开,树枝节点和叶子节点不具有相同的接口,客户端调用需要做响应的判断,带来不便。
/**
* 抽象接口
* 没有add()和remove()方法
*/
public interface Component {
// 显示所有树枝和叶子构件
void display(int depth);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
/**
* 树枝节点
* 实现add()和remove()方法
*/
public class Composite implements Component {
private String name;
public Composite(String name) {
this.name = name;
}
private List<Component> children = new ArrayList<>();
// 添加树枝或叶子构件
public void add(Component component) {
children.add(component);
}
// 移除构件
public void remove(Component component) {
children.remove(component);
}
@Override
public void display(int depth) {
// 列出树形结构
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
// 遍历下级
for (Component component : children) {
component.display(depth + 1);
}
}
}
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
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
/**
* 叶子节点
* 没有add()和remove()方法
*/
public class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 测试类
* 安全模式,树枝节点和叶子节点分开,树枝节点和叶子节点不具有相同的接口,客户端调用需要做响应的判断,带来不便。
*/
public class Client {
public static void main(String[] args) {
// 树枝构件
Composite user = new Composite("用户管理");
Composite role = new Composite("角色管理");
Composite menu = new Composite("菜单管理");
// 抽象构件
Composite system = new Composite("系统管理");
system.add(user);
system.add(role);
system.add(menu);
// 叶子构件
Leaf addUser = new Leaf("添加用户");
Leaf editUser = new Leaf("编辑用户");
Leaf removeUser = new Leaf("删除用户");
user.add(addUser);
user.add(editUser);
user.add(removeUser);
system.display(1);
}
}
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
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
// Make sure to add code blocks to your code group
上次更新: 2023/11/17, 09:38:49