组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。
组合模式可以在需要针对“树形结构”进行操作的应用中使用,例如扫描文件夹、渲染网站导航结构等等。
这里用代码模拟文件扫描功能,封装了File
和Folder
两个类。在组合模式下,用户可以向Folder
类嵌套File
或者Folder
来模拟真实的“文件目录”的树结构。
同时,两个类都对外提供了scan
接口,File
下的scan
是扫描文件,Folder
下的scan
是调用子文件夹和子文件的scan
方法。整个过程采用的是深度优先。
class File: # 文件类def __init__(self, name):self.name = namedef add(self):raise NotImplementedError()def scan(self):print('扫描文件:' + self.name)class Folder: # 文件夹类def __init__(self, name):self.name = nameself.files = []def add(self, file):self.files.append(file)def scan(self):print('扫描文件夹: ' + self.name)for item in self.files:item.scan()if __name__ == '__main__':home = Folder("用户根目录")folder1 = Folder("第一个文件夹")folder2 = Folder("第二个文件夹")file1 = File("1号文件")file2 = File("2号文件")file3 = File("3号文件")# 将文件添加到对应文件夹中folder1.add(file1)folder2.add(file2)folder2.add(file3)# 将文件夹添加到更高级的目录文件夹中home.add(folder1)home.add(folder2)# 扫描目录文件夹home.scan()
执行$ python main.py
, 最终输出结果是:
扫描文件夹: 用户根目录扫描文件夹: 第一个文件夹扫描文件:1号文件扫描文件夹: 第二个文件夹扫描文件:2号文件扫描文件:3号文件
// 文件类class File {constructor(name) {this.name = name || "File";}add() {throw new Error("文件夹下面不能添加文件");}scan() {console.log("扫描文件: " + this.name);}}// 文件夹类class Folder {constructor(name) {this.name = name || "Folder";this.files = [];}add(file) {this.files.push(file);}scan() {console.log("扫描文件夹: " + this.name);for (let file of this.files) {file.scan();}}}let home = new Folder("用户根目录");let folder1 = new Folder("第一个文件夹"),folder2 = new Folder("第二个文件夹");let file1 = new File("1号文件"),file2 = new File("2号文件"),file3 = new File("3号文件");// 将文件添加到对应文件夹中folder1.add(file1);folder2.add(file2);folder2.add(file3);// 将文件夹添加到更高级的目录文件夹中home.add(folder1);home.add(folder2);// 扫描目录文件夹home.scan();
执行$ node main.js
,最终输出结果是:
扫描文件夹: 用户根目录扫描文件夹: 第一个文件夹扫描文件: 1号文件扫描文件夹: 第二个文件夹扫描文件: 2号文件扫描文件: 3号文件