一、定义
组合模式就是用小的子对象来构建更大的对象,而这些子对象本身也许使用更小的孙对象构成的
二、举例
操作文件夹
三、结构
组合模式包含两种对象:叶对象和叶对象组合而成的组合对象。由组合对象和叶对象构成了树结构,这种树结构就是组合模式的基本结构。如下图所示:
四、实现
组合模式事实上就是一个树结构,就像前端在渲染一个类似机构树结构,需要后端将树结构传到前端。虽然传到前端的结构只是一个json格式,但事实上这个机构的每一个节点在后端都是一个节点对象,我们判断节点是否为叶子节点往往是通过判断其是否存在子节点。这和组合模式很相似,不同点在于,后端的节点对象一般都是同一个对象,这样的话,这个对象可能不需要实现任何抽象类。但是组合模式中的节点需要分为两个对象:组合对象和叶对象,这两种对象需要实现同一个抽象类,这也就决定了二者的接口是相同的。下面以一个扫描文件夹的例子为例:
// 组合对象 var Folder = function(name){ this.name = name; this.files = []; }; Folder.prototype.add = function(file){ this.files.push(file); }; Folder.prototype.scan = function(){ console.log("开始扫描文件夹:" + this.name); for(var i = 0, l = this.files.length; i < l; i++){ this.files[i].scan(); } }; // 叶对象 var File = function(name){ this.name = name; }; File.prototype.add = function(){ throw new Error("文件下不能添加文件"); }; File.prototype.scan = function(){ console.log("开始扫描文件夹:" + this.name); }; var folder = new Folder("计算机"); var folder1 = new Folder("系统"); var folder2 = new Folder("学习"); var file1 = new File("system32.config"); var file2 = new File("system64.config"); var file3 = new File("react"); var file4 = new File("vue"); folder.add(folder1); folder.add(folder2); folder1.add(file1); folder1.add(file2); folder2.add(file3); folder2.add(file4); folder.scan(); // 调用扫描方法
// 开始扫描文件夹:计算机
// 开始扫描文件夹:系统
// 开始扫描文件夹:system32.config
// 开始扫描文件夹:system64.config
// 开始扫描文件夹:学习
// 开始扫描文件夹:react
// 开始扫描文件夹:vue
由此可以对于用户而言,仅仅知道最顶端的组合对象,调用这个对象的方法,请求就会沿着树往下传递,一次到达所有的节点。并且每次对最上层的对象进行一次请求的时候,实际上是对整个树进行深度优先搜索。