大数据

javascript组合模式

在程序设计中,组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也是由更小的对象组成的。这里只是组合,并没有从属关系。参考《javascript设计模式与开发实践》第十章

//宏命令的代码
var closeDoorCommand = {//作为叶对象
        execute: function(){
            console.log( '关门' );
        }
    };
    var openPcCommand = { //作为叶对象
        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 ( var i = 0, command; command = this.commandsList[ i++ ]; ){
                    command.execute(); //叶对象都有execute方法
                }
            }
        }
    };
    var macroCommand = MacroCommand();
    macroCommand.add( closeDoorCommand );//添加到根对象数组中
    macroCommand.add( openPcCommand );//同上
    macroCommand.add( openQQCommand );//同上
    macroCommand.execute();//执行根命令

两个要点:1.js对象引用可以作为数组元素加入到数组中。2. 叶对象都有一样的execute方法。在根对象执行的时候,可以使用leaf.execute的模式来调用对象的方法。

在叶对象中还可以继续扩展也对象,组合的深度继续加深。

var MacroCommand = function(){ //根对象的方法保持不变
        return {
            commandsList: [],
            add: function( command ){
                this.commandsList.push( command );
            },
            execute: function(){
                for ( var 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 = MacroCommand(); //第一个叶对象
macroCommand1.add( openTvCommand ); //添加下一级叶对象
macroCommand1.add( openSoundCommand );//同上
/*********关门、打开电脑和打登录QQ 的命令****************/
var closeDoorCommand = {
    execute: function(){
        console.log( '关门' );
    }
};
var openPcCommand = {
    execute: function(){
        console.log( '开电脑' );
    }
};
var openQQCommand = {
    execute: function(){
        console.log( '登录QQ' );
    }
};
var macroCommand2 = MacroCommand();//第二个叶对象
macroCommand2.add( closeDoorCommand );//添加下一级叶对象
macroCommand2.add( openPcCommand );//同上
macroCommand2.add( openQQCommand );
/*********现在把所有的命令组合成一个“超级命令”**********/
var macroCommand = MacroCommand(); //顶级根对象
macroCommand.add( openAcCommand ); //一个叶对象
macroCommand.add( macroCommand1 ); //另一个
macroCommand.add( macroCommand2 ); //另一个
/*********最后给遥控器绑定“超级命令”**********/
var setCommand = (function( command ){
    document.getElementById( 'button' ).onclick = function(){
        command.execute();
    }
})( macroCommand );


//最终所有的叶对象的引用都添加到commandlist数组中,在根对象上执行
//execute方法时,会遍历所有的叶对象,并执行leaf.execute()方法。
//得到结果
最终还是使用了javascript的数组操作和对象操作的便利性。在javascript的模式设计中,基本都是在操作数组和对象。所有有必要还好在深刻理解一下数组对象的方法。

这个系列写了好几篇文章了。其实写的时候好多地方还不太懂,写着写着有些地方就明白了,所以还是要坚持写下去。现在觉得写的还不错,过半年可能觉得就很傻了。