在程序设计中,组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也是由更小的对象组成的。这里只是组合,并没有从属关系。参考《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的模式设计中,基本都是在操作数组和对象。所有有必要还好在深刻理解一下数组对象的方法。
这个系列写了好几篇文章了。其实写的时候好多地方还不太懂,写着写着有些地方就明白了,所以还是要坚持写下去。现在觉得写的还不错,过半年可能觉得就很傻了。