设计模式之-组合模式

先来看一段代码,这也是上一片命令模式中的宏命令的代码,

javascript 复制代码
	var closeDoorCommand = {
        execute:function(){
            console.log('关门')
        }
    };
    var openDoorCommand = {
        execute:function(){
            console.log('开门')
        }
    }
    var openQQCommand = {
        execute:function(){
            console.log('登陆QQ')
        }
    }
    var MacroCommand = function(){
        return {
            commandsList:[],
            add:function(command){
                this.commandsList.push(command);
            },
            execute:function(){
                for(let i=0,command;command=this.commandsList[i++];){
                    command.execute();
                }
            }
        }
    }

    var macroCommand = MacroCommand();
    macroCommand.add(closeDoorCommand);
    macroCommand.add(openDoorCommand);
    macroCommand.add(openQQCommand);
    macroCommand.execute();

通过这段代码,很容易发现宏命令中包含一组字命令,他们组成了一个树形结构,这是一颗结构非常简单的树。

其中,macroCommand被称为组合对象,closeDoorCommand,openDoorCommand,openQQCommand都是叶对象。在macroCommand的execute的方法里,并不执行真正的操作,而是遍历它所包含的叶对象,把真正的execute请求委托给这些叶对象。

组合模式的用途

1.表示树形结构

2.利用对象多态性统一对待组合对象和单个对象。

目前的万能遥控器包含关门、开电脑、登陆QQ这3个功能,现在需要一个超级万能遥控器,可以控制家里所有的电器,他拥有以下功能:

1 打开空调,2 打开电视和音响 3. 关门、开电脑、登陆QQ

html 复制代码
 <button id="button">按我</button>
   <script>
    var MacroCommand = function(){
        return {
            commandsList:[],
            add:function(command){
                this.commandsList.push(command);
            },
            execute:function(){
                for(let i=0,command;command=this.commandsList[i++];){
                    command.execute();
                }
            }
        }
    }

    var openAcCommand = {
        execute:function(){
            console.log('打开空调');
        }
    }
    // 家里的电视和音响是连接在一起的,所以可以用一个宏命令来组合打开电视和打开音响的命令
    var openTvCommand = {
        execute:function(){
            console.log('打开电视');
        }
    }
    var openSoundCommand = {
        execute:function(){
            console.log('打开音响');
        }
    }
    var macroCommand1=new MacroCommand();
    macroCommand1.add(openTvCommand);
    macroCommand1.add(openSoundCommand);
    
    // 关门、打开电脑和打开登陆QQ的命令
     var closeDoorCommand = {
        execute:function(){
            console.log('关门')
        }
    };
    var openDoorCommand = {
        execute:function(){
            console.log('开门')
        }
    }
    var openQQCommand = {
        execute:function(){
            console.log('登陆QQ')
        }
    }
    var macroCommand2 = MacroCommand();
    macroCommand2.add(closeDoorCommand);
    macroCommand2.add(openDoorCommand);
    macroCommand2.add(openQQCommand);

    // 现在把所有的命令组合成一个超级命令
    var macroCommand = new MacroCommand();
    macroCommand.add(openAcCommand);
    macroCommand.add(macroCommand1);
    macroCommand.add(macroCommand2);
    // 最后给遥控器绑定超级命令
    var setCommand = (function(command){
        document.getElementById('button').onclick=function(){
            command.execute();
        }
    })(macroCommand)
   </script>

扫描文件夹的demo

javascript 复制代码
		// Folder
        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,file,files=this.files;file=files[i++];){
                file.scan();
            }
        };

        // file
        var File = function(name){
            this.name=name;
        };
        File.prototype.add=function(){
            throw new Error('文件下面不能在添加文件');
        };
        File.prototype.scan=function(){
            console.log('开始扫描文件:'+this.name);
        };
        // 接下来创建一些文件夹和文件对象,并且让他们组合成一棵树,这棵树就是我们F盘里现有的文件目录结构
        var folder = new Folder('学习资料');
        var folder1 = new Folder('JavaScript');
        var folder2 = new Folder('jQuery');

        var file1 = new File('javascript设计模式与开发实栈');
        var file2 = new File('精通JQuery');
        var file3 = new File('重构与模式');

        folder1.add(file1);
        folder2.add(file2);

        folder.add(folder1);
        folder.add(folder2);
        folder.add(file3);

        // 现在的需求是吧移动硬盘里的文件和文件夹都复制到这棵树中,假设我们已经得到了这些文件对象
        var folder3 = new Folder('Node.js');
        var file4=new File('深入浅出Node.js');
        folder3.add(file4);

        var file5=new File('javascript语言精髓与编程实践');
        // 接下来就是把这些文件都添加到原有的树中
        folder.add(folder3);
        folder.add(file5);

        folder.scan();

非原创,来源javascript设计模式与开发实践 -曾探

相关推荐
天下一般2 小时前
go语言设计模式<一>模板方法
开发语言·设计模式·golang
syt_10132 小时前
设计模式之-命令模式
设计模式·命令模式
有一个好名字2 小时前
设计模式-工厂方法模式
java·设计模式·工厂方法模式
阿波罗尼亚4 小时前
Head First设计模式(十三) 设计原则 现实世界中的模式
设计模式
sg_knight4 小时前
Python 中的常用设计模式工具与库
开发语言·python·设计模式
雨中飘荡的记忆1 天前
享元模式深度解析:看Java如何优雅节省内存
java·设计模式
How_doyou_do1 天前
Agent设计模式与工程化
设计模式
_膨胀的大雄_1 天前
01-创建型模式
前端·设计模式
是2的10次方啊1 天前
🎭 程序员的周末:11种设计模式继续藏在你身边
设计模式