树形结构
;一致对待
;想象我们现在手上有个万能遥控器, 当我们回家, 按一下开关, 下列事情将被执行:
1. 煮咖啡2. 打开电视、打开音响3. 打开空调、打开电脑
我们把任务划分为 3 类, 效果图如下:
接着看看结合了命令模式和组合模式的具体实现:
const MacroCommand = function() {return {lists: [],add: function(task) {this.lists.push(task)},excute: function() { // ①: 组合对象调用这里的 excute,for (let i = 0; i < this.lists.length; i++) {this.lists[i].excute()}},}}const command1 = MacroCommand() // 基本对象command1.add({excute: () => console.log('煮咖啡') // ②: 基本对象调用这里的 excute,})const command2 = MacroCommand() // 组合对象command2.add({excute: () => console.log('打开电视')})command2.add({excute: () => console.log('打开音响')})const command3 = MacroCommand()command3.add({excute: () => console.log('打开空调')})command3.add({excute: () => console.log('打开电脑')})const macroCommand = MacroCommand()macroCommand.add(command1)macroCommand.add(command2)macroCommand.add(command3)macroCommand.excute()// 煮咖啡// 打开电视// 打开音响// 打开空调// 打开电脑
可以看出在组合模式中基本对象和组合对象被一致对待, 所以要保证基本对象(叶对象)和组合对象具有一致方法。
扫描文件夹时, 文件夹下面可以为另一个文件夹也可以为文件, 我们希望统一对待这些文件夹和文件, 这种情形适合使用组合模式。
const Folder = function(folder) {this.folder = folderthis.lists = []}Folder.prototype.add = function(resource) {this.lists.push(resource)}Folder.prototype.scan = function() {console.log('开始扫描文件夹: ', this.folder)for (let i = 0, folder; folder = this.lists[i++];) {folder.scan()}}const File = function(file) {this.file = file}File.prototype.add = function() {throw Error('文件下不能添加其它文件夹或文件')}File.prototype.scan = function() {console.log('开始扫描文件: ', this.file)}const folder = new Folder('根文件夹')const folder1 = new Folder('JS')const folder2 = new Folder('life')const file1 = new File('深入React技术栈.pdf')const file2 = new File('JavaScript权威指南.pdf')const file3 = new File('小王子.pdf')folder1.add(file1)folder1.add(file2)folder2.add(file3)folder.add(folder1)folder.add(folder2)folder.scan()// 开始扫描文件夹: 根文件夹// 开始扫描文件夹: JS// 开始扫描文件: 深入React技术栈.pdf// 开始扫描文件: JavaScript权威指南.pdf// 开始扫描文件夹: life// 开始扫描文件: 小王子.pdf