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