Zer0e's Blog

设计模式之组合模式

字数统计: 986阅读时长: 4 min
2020/09/17 Share

前言

这篇是23种设计模式的最后一篇了,不知不觉整理了一个月,其实应该快点整理完,每天一到两篇文章虽然量不多,但是写的时候其实挺累人。言归正传,本文来讲最后一种设计模式,组合模式。

正文

概念

组合模式又称部分整体模式,它属于结构型模式,通常适用于有结构的系统,用于表示部分与整体层次。顺带一提,这里的有结构一般是树形结构。
那这个模式他模糊了简单元素与复杂元素的概念,可以统一使用同一个对象来进行操作。
那常见的场景有,上下级关系的构建,或者是文件系统的构建。

实现

那我们就来简单实现一个文件系统,我们知道一般文件系统包括普通文件和文件夹,但是学过操作系统后我们知道,文件夹其实是一种特殊的文件,在标志处不一样而已。那我们就来实现这个系统。
首先我们创建抽象类File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class File {
private String name;

public File(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public abstract void display();
}

这里的display方法如果是文件夹是显示它所有文件,如果是文件则打印文件名。
接着我们创建Folder。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Folder extends File{
private List<File> fileList;
public Folder(String name) {
super(name);
fileList = new ArrayList<>();
}

@Override
public void display() {
for (File file : fileList){
file.display();
}
}

public void add(File file){
fileList.add(file);
}

public void remove(File file){
fileList.remove(file);
}
}

接着我们创建两种类型的文件,文本文件和图片文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class TextFile extends File{

public TextFile(String name) {
super(name);
}

@Override
public void display() {
System.out.println("文本文件,文件名为:" + super.getName());
}
}
public class ImageFile extends File{
public ImageFile(String name) {
super(name);
}

@Override
public void display() {
System.out.println("图片文件,文件名为:" + super.getName());
}
}

最后我们创建客户端调用试试,我们创建一个这样的文件系统,有一个文件夹all,包含1.txt,1.jpg,还有一个文件夹1;然后文件夹1中还有2.txt和2.jpg。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Client {
public static void main(String[] args) {
Folder all = new Folder("all");
File txt1 = new TextFile("1.txt");
File txt2 = new TextFile("2.txt");

File jpg1 = new ImageFile("1.jpg");
File jpg2 = new ImageFile("2.jpg");

Folder folder1 = new Folder("1");

all.add(txt1);
all.add(jpg1);
all.add(folder1);

folder1.add(txt2);
folder1.add(jpg2);

all.display();
folder1.display();
}
}

那这里就有个问题,就是总文件夹中打印文件名时,会把子文件夹中的一并打印出来,那么这时候我们可以在抽象类中设置一个type属性,依照参数,比如-r表示是否递归,来判断是否递归打印。通过判断type来实现,这里就不实现了,感兴趣的可以自行实现。

优缺点

那组合模式的优点是可以定义一些分层次的对象,添加组件也很简单。其次就是客户端调用简单。最后就是符合开闭原则,添加新的组件不用修改原有代码。
那缺点在于整个系统会变得抽象,维护成本增加,其次就是违反依赖导致原则,就像上文的例子一样,客户端要创建文件夹时,需要依赖的是Folder实现类,而不是File抽象类。

后言

那设计模式这个系列到这里基本上是告一段落了,前前后后整理这个系列花了一个多月的时间,那接下来可能还是会写一些自己感兴趣的话题或者技术,有时间的话博客还是会坚持写下去的。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 优缺点
  3. 3. 后言