Design Patterns(八) Composite

The composite pattern applies when there is a part-whole hierarchy of objects and a client needs to deal with objects uniformly regardless of the fact that an object might be a leaf or a branch.

前言

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

组合模式

基本介绍:

1) 组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系;
2) 组合模式依据树形结构来组合对象,用来表示部分以及整体层次;
3) 这种类型的设计模式属于结构型模式;
4) 组合模式使得用户对单个对象和组合对象的访问具有一致性, 即 :组合能让客户以一致的方式处理个别对象以及组合对象。

组合模式的三种角色:

1)Component(抽象组件角色): 是组合模式中Composite和Leaf共同的父接口(抽象类),在此接口中声明所有子类的共有的方法;
2)Composite(枝节点角色):枝节点,即本模式中的“整体”角色,它包含子节点,字节点既可以是枝节点,也可以是叶节点;例如文件系统中的文件夹;
3)Leaf(叶节点角色): 叶子节点,即没有字节点的节点,本模式中的“部分”角色,例如文件系统中文件。

组合模式-UML图:





组合模式-案例图:



代码:

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import java.util.ArrayList;
import java.util.List;

/**
* @Auther: Arsenal
* @Date: 2020-03-14 20:49
* @Description: 组合模式
*/
public class Composite {
public static void main(String[] args) {

OrganizationComponent university = new University("清华大学", "Great University in China");
OrganizationComponent computerCollege = new College("计算机学院", "College of Computing");
OrganizationComponent engineeringCollege = new College("工程学院", "College of Engineering");
university.add(computerCollege);
university.add(engineeringCollege);

computerCollege.add(new Department("软件工程", "Software Engineering"));
computerCollege.add(new Department("信息工程", "Information Engineering"));
computerCollege.add(new Department("计算机科学与计算", "Computer Science and Technology"));

engineeringCollege.add(new Department("航空航天工程", "Aeronautical Engineering"));
engineeringCollege.add(new Department("核工程", "Nuclear engineering"));
engineeringCollege.add(new Department("生物医学工程", "Biomedical Engineering"));

university.printMsg();
computerCollege.printMsg();
engineeringCollege.printMsg();
}
}

/**
* Component
*/
abstract class OrganizationComponent {
String name;
String description;

OrganizationComponent(String name, String description) {
this.name = name;
this.description = description;
}

void add(OrganizationComponent organizationComponent) {
}

void remove(OrganizationComponent organizationComponent) {
}

void printMsg() {
}
}

/**
* Composite
*/
class University extends OrganizationComponent {

List<OrganizationComponent> components = new ArrayList<>();

University(String name, String description) {
super(name, description);
}

@Override
void add(OrganizationComponent component) {
components.add(component);
}

@Override
void remove(OrganizationComponent component) {
if (components.size() == 0) {
return;
}
components.remove(component);
}

@Override
void printMsg() {
System.out.println("********" + this.name + "********" + this.description + "********");
if (components.size() == 0) {
return;
}
for (OrganizationComponent component : components) {
System.out.println("" + component.name + "-->" + "component.description");
}
}
}

/**
* Composite
*/
class College extends OrganizationComponent {

List<OrganizationComponent> components = new ArrayList<>();

College(String name, String description) {
super(name, description);
}

@Override
void add(OrganizationComponent component) {
components.add(component);
}

@Override
void remove(OrganizationComponent component) {
if (components.size() == 0) {
return;
}
components.remove(component);
}

@Override
void printMsg() {
System.out.println("========" + this.name + "========" + this.description + "========");
if (components.size() == 0) {
return;
}
for (OrganizationComponent component : components) {
System.out.println("" + component.name + "-->" + "component.description");
}
}
}

/**
* leaf
*/
class Department extends OrganizationComponent {

Department(String name, String description) {
super(name, description);
}

@Override
void printMsg() {
System.out.println("--------" + this.name + "--------" + this.description + "--------");
}
}

总结

组合模式的注意事项和细节:

1) 简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题;
2) 具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动;
3) 方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构;
4) 需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式;
5) 要求较高的抽象性, 如果节点和叶子有很多差异性的话 ,比如很多方法和属性都不一样,不适合使用组合模式。

延伸

    组合模式
    组合模式-菜鸟教程
    Composite Pattern
    Composite Design Pattern
    组合模式-Composite Pattern
    尚硅谷Java设计模式,韩顺平图解java设计模式

Content
  1. 1. 前言
  2. 2. 组合模式
  3. 3. 总结
  4. 4. 延伸