理解设计模式(九)——组合模式

组合模式

理解设计模式(一)——简单工厂 理解设计模式(二)——工厂方法 理解设计模式(四)——建造者 理解设计模式(五)——原型模式 理解设计模式(六)——单例模式 理解设计模式(七)——适配器模式 理解设计模式(八)——桥接模式

提出问题

许多对象与对象之间往往存在着一种类似于递归的关系。比如说,如果我们要实现一个文件系统,其中有文件对象文件夹对象。文件夹中可能会同时包含文件和文件夹。文件夹中的文件夹还可能有文件和文件夹。

我们如何设计一种合理的结构来表现这样的关系?答案就是使用组合模式。

解决问题

首先,不管是文件对象还是文件夹对象,我们都统一看成是抽象文件

之所以这样做,其实是对于强类型语言来说的。因为文件夹中可能会同时有文件和文件夹,并且我们必然需要一个类似于数组的数据结构来存储这些文件和文件夹。如果我们把文件和文件夹拆分为两个独立的类,对于强类型语言来说,可能就需要使用两个数组分别进行存储,后面处理起来也不太方便。如果是像Javascript这样的弱类型语言就没有这样的问题,因为数组中本来就可以存储不同类型的变量。

下面使用实际的代码🌰来理解:

// 假设是强类型语言,需要进行继承
class AbstractFile {
// 文件夹添加文件
Add(file) {}

// 文件夹删除文件
Remove(file) {}

// 文件夹获取内部文件
GetChild(index) {}

// 访问文件/文件夹
Visit() {}
}

class File extends AbstractFile {
constructor(name) {
this.name = name; // 文件名
}

Add(file) {}

Remove(file) {}

GetChild(index) {}

Visit() {
// 实现文件访问
// ...
}
}

class Folder extends AbstractFile {
constructor(name) {
this.fileList = [];
this.name = name;
}

Add(file) {
// 添加文件/文件夹
this.fileList.push(file);
}

Remove(file) {
// 移除文件/文件夹
// ...
}

GetChild(index) {
// 获取第index节点的子节点
// ...
}

Visit() {
// 实现文件夹访问
// ...
}
}
Author: LeoB_O
Link: https://leob-o.github.io/2019/06/06/CompositePattern/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.