组合模式
介绍
也称为整体部分模式,结构型设计模式之一,组合模式比较简单,他将一组相似的对象看作一个对象处理,并根据一个树状结构来组合对象,然后提供一个统一的方法去访问响应的对象,以此忽略掉对象跟对象集合之间的差别。生活中比较典型的例子就是组织结构的树状图。
一个公司有行政部,研发部,同时还有子公司,子公司里也有行政部跟研发部。
在这里虽然总公司跟子公司其本质不一样,但是他们的组织结构是一样的,我们可以把他们看作是一个抽象的公司,在组合模式中我们将这样一个拥有分支的节点称之为枝干构件,位于树状结构顶部的枝干结构比较特殊,我们称之为根结构件,因为其为整个树状结构的始端,同样对于像行政部和研发部这样的没有分支的结构,我们则称之为叶子构件,这样的一个结构就是组合模式的雏形。
标准定义:将对象组合成树形结构以表示”整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
使用场景
- 表示对象的部分-整体层次结构的时候
- 从一个整体中能够独立出部分模块或功能的场景
角色介绍
- Component
- Composite
- Leaf
- Client
Component :抽象根节点,为组合中的对象声明接口。在适当情况下,实现所有类共有接口的缺省的行为。声明一个结构用于访问跟管理Component的子节点。可在递归结构中定一个接口,用于访问一个父节点,并在合适的时候,实现它。
Composite:定义有子节点的那些枝干节点的行为,存储子节点,在Component接口中实现与子节点有关的操作。
Leaf:在组合中表示叶子节点对象,叶子节点没有子节点,在组合中定义节点对象的行为。
Client:通过Component接口操纵组合节点的对象。
组合模式的模板
1 | public abstract class Component { |
1 | public class Composite extends Component { |
1 | public class Leaf extends Component { |
1 | public class Client { |
简单实现
操作系统的文件系统
表示文件或者文件夹的抽象类
1 | public abstract class Dir { |
文件夹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
45public class Folder extends Dir {
public Folder(String name) {
super(name);
}
@Override
public void addDir(Dir dir) {
dirs.add(dir);
}
@Override
public void rmDir(Dir dir) {
dirs.remove(dir);
}
@Override
public void clear() {
dirs.clear();
}
//首先输出自己的名字,然后迭代遍历子元素,调用子元素的print方法输出其目录结构,
// 如果遇到子元素还是个文件夹,那么递归遍历直至所有的输出元素均为文件为止。
@Override
public void print() {
System.out.print(getName()+"(");
Iterator<Dir> iterator = dirs.iterator();
while(iterator.hasNext()){
Dir dir = iterator.next();
dir.print();
if(iterator.hasNext()){
System.out.print(",");
}
}
System.out.print(")");
}
@Override
public List<Dir> getFiles() {
return dirs;
}
}
文件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
31public class File extends Dir {
public File(String name) {
super(name);
}
@Override
public void addDir(Dir dir) {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void rmDir(Dir dir) {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void clear() {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void print() {
System.out.print(getName());
}
@Override
public List<Dir> getFiles() {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
}
客户端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
28public class client {
public static void main(String[] args){
Dir diskC = new Folder("C");
diskC.addDir(new File("first.text"));
Dir dirWin = new Folder("windows");
dirWin.addDir(new File("explorer.exe"));
diskC.addDir(dirWin);
Dir dirPer = new Folder("PerfLogs");
dirPer.addDir(new File("null.txt"));
diskC.addDir(dirPer);
Dir dirPro = new Folder("Program File");
dirPro.addDir(new File("ftp.txt"));
diskC.addDir(dirPro);
diskC.print();
}
}