设计模式之-组合模式

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

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设计模式与开发实践 -曾探

相关推荐
阿星AI工作室5 小时前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦1 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo4 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4964 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃4 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式
驴儿响叮当20104 天前
设计模式之状态模式
设计模式·状态模式
电子科技圈4 天前
XMOS推动智能音频等媒体处理技术从嵌入式系统转向全新边缘计算
人工智能·mcu·物联网·设计模式·音视频·边缘计算·iot
徐先生 @_@|||5 天前
安装依赖三方exe/msi的软件设计模式
设计模式
希望_睿智5 天前
实战设计模式之访问者模式
c++·设计模式·架构
茶本无香5 天前
设计模式之十六:状态模式(State Pattern)详解 -优雅地管理对象状态,告别繁琐的条件判断
java·设计模式·状态模式