我是靠谱客的博主 清秀蛋挞,这篇文章主要介绍“部分-整体“——组合模式,现在分享给大家,希望可以做个参考。

一、组合模式概述

1.定义:
组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

2.例子:
在这里插入图片描述
3.分析:
在树形目录结构中,包含文件和文件夹两类不同的元素。
在文件夹中可以包含文件,还可以继续包含子文件夹,在文件中不能再包含子文件或者子文件夹。
文件夹 —>容器(Container)
文件 —>叶子(Leaf)

4.理解:
一致地对待容器对象和叶子对象。
当容器对象的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象并调用执行,牵一而动百,其中使用了递归调用的机制来对整个结构进行处理
由于容器对象和叶子对象在功能上的区别,在使用这些对象的代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使程序非常复杂
在这里插入图片描述
5.结构:
组合模式包含以下3个角色:Component(抽象构件)、Leaf(叶子构件)、Composite(容器构件)

二、组合模式适用环境

1.在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们
2.在一个使用面向对象语言开发的系统中需要处理一个树形结构
3.在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型

三、组合模式案例

1.案例:
软件公司欲开发一个杀毒软件,该软件既可以对某个文件夹(Folder)杀毒,也可以对某个指定的文件(File)进行杀毒。该杀毒软件还可以根据各类文件的特点,为不同类型的文件提供不同的杀毒方式,例如图像文件(ImageFile)和文本文件(TextFile)的杀毒方式就有所差异。现使用组合模式来设计该杀毒软件的整体框架。
2.类图:
在这里插入图片描述
(1) AbstractFile:抽象文件类,充当抽象构件类
(2) ImageFile:图像文件类,充当叶子构件类
(3) TextFile:文本文件类,充当叶子构件类
(4) Folder:文件夹类,充当容器构件类
(5) Client:客户端测试类
3.代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
package composite; /** * 抽象文件类,充当抽象构件类 */ public abstract class AbstractFile { public abstract void add(AbstractFile file); //添加元素 public abstract void remove(AbstractFile file); //删除元素 public abstract void killVirus(); //模拟杀毒 }
复制代码
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
package composite; import java.util.ArrayList; /** * 文件夹类,充当容器构件类 */ public class Folder extends AbstractFile { //定义一个fileList的集合,用来存储AbstractFile类型的成员 private ArrayList<AbstractFile> fileList = new ArrayList<>(); private String name; //定义文件夹名 //无参构造 public Folder() { } //有参构造 public Folder(String name) { this.name = name; } @Override public void add(AbstractFile file) { fileList.add(file); } @Override public void remove(AbstractFile file) { fileList.remove(file); } @Override public void killVirus() { System.out.println("系统正在对‘" + name + "’进行杀毒"); //利用foreach循环对fileList集合里的所有元素进行杀毒 for (AbstractFile abstractFile : fileList) { abstractFile.killVirus(); } } }
复制代码
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
package composite; /** * 图像文件类,充当叶子构件类 */ public class ImageFile extends AbstractFile { private String name; //定义文件名 //无参构造 public ImageFile() { } //有参构造 public ImageFile(String name) { this.name = name; } @Override public void add(AbstractFile file) { System.out.println("对不起,不支持该方法!"); } @Override public void remove(AbstractFile file) { System.out.println("对不起,不支持该方法!"); } @Override public void killVirus() { System.out.println("系统正在对‘" + name + "’进行图像杀毒"); } }
复制代码
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
package composite; /** * 文本文件类,充当叶子构件类 */ public class TextFile extends AbstractFile { private String name; //定义文件名 //无参构造 public TextFile() { } //有参构造 public TextFile(String name) { this.name = name; } @Override public void add(AbstractFile file) { System.out.println("对不起,不支持该方法!"); } @Override public void remove(AbstractFile file) { System.out.println("对不起,不支持该方法!"); } @Override public void killVirus() { System.out.println("系统正在对‘" + name + "’进行文本杀毒"); } }
复制代码
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
package composite; /** * 客服端测试类 */ public class Client { public static void main(String[] args) { /* 1.创建对象 */ //创建文件夹对象 AbstractFile folder = new Folder("Bei-Zhen的资料"); //创建子文件夹对象 AbstractFile subfolder1 = new Folder("图像文件夹"); AbstractFile subfolder2 = new Folder("文本文件夹"); //创建文件对象(图像文件或文本文件) AbstractFile file1 = new ImageFile("百度登录流程图.jpg"); AbstractFile file2 = new ImageFile("猜拳流程图.png"); AbstractFile file3 = new TextFile("设计模式.txt"); AbstractFile file4 = new TextFile("面向对象基础.doc"); /* 2.向集合中添加元素 */ //把文件添加到相对应的子文件夹中 subfolder1.add(file1); subfolder1.add(file2); subfolder2.add(file3); subfolder2.add(file4); //把子文件夹添加到文件夹中 folder.add(subfolder1); folder.add(subfolder2); /* 3.对文件夹杀毒 */ System.out.println("---------------杀毒软件--------------------"); System.out.println("------文件夹杀毒开始,正在闪电杀毒-----------"); folder.killVirus(); System.out.println("------文件夹杀毒完成,感谢你的使用-----------"); System.out.println(); /* 4.对指定文件杀毒 */ System.out.println("------指定文件杀毒开始,正在闪电杀毒---------"); file1.killVirus(); System.out.println("------指定文件杀毒完成,感谢你的使用---------"); } }

4.代码运行截图:
在这里插入图片描述

四、组合模式优缺点

1.优点:
(1)可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构进行控制
(2)客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
(3)增加新的容器构件和叶子构件都很方便,符合开闭原则
(4)为树形结构的面向对象实现提供了一种灵活的解决方案
2.缺点:
在增加新构件时很难对容器中的构件类型进行限制

最后

以上就是清秀蛋挞最近收集整理的关于“部分-整体“——组合模式的全部内容,更多相关“部分-整体“——组合模式内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(96)

评论列表共有 0 条评论

立即
投稿
返回
顶部