JavaScript组合模式
组合模式的用途:
1.组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。
2.利用对象多态性统一对待组合对象和单个对象。在组合模式中,客户将统一地使用组合结构中的所有对象,而不需要关心它究竟是组合对象还是单个对象
这在实际开发中给客户带来很大的便利性,当我们往万能遥控器里面添加一个命令的时候,并不关心这个命令是宏命令还是普通子命令。我们只需要确定它是一个命令,并且这个命令拥有可执行的execute方法,那么这个命令就可以被添加进万能遥控器。
在组合模式中,请求在书中传递的过程总是遵循一种逻辑。
以宏命令为例,请求从树最顶端的对象往下传递,如果当前处理请求的对象是叶对象(普通子命令),叶对象自身会对请求作出相应的处理;如果当前处理请求的对象是组合对象(宏命令),组合对象则会遍历它属下的子节点,将请求继续传递。如下图:
更强大的宏命令:
目前的万能遥控器,包含了关门、开电脑、登录QQ、打开电视和音响、打开空调等功能,相关代码如下:
<html>
<body>
<button id="button">按我</button>
<script>
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 setCommand = (function(command){
document.getElementById('button').onclick = function(){
command.ececute(); //只需调用一次
}
})(macroCommand);
</script>
</body>
</html>
当按下遥控器的按钮时,所有命令都将被依次执行:
打开空调 -->> 打开电视 -->> 打开音响 -->> 关门 -->> 开电脑 -->> 登QQ
组合模式的实例:扫描文件夹。文件夹和文件之间的关系非常适合用组合模式来描述。文件夹里既可以包含文件又可以包含文件夹,最终可以组合成一棵树。
组合模式可以让我们使用树形方式创建对象的结构,我们可以把相同的操作应用在组合对象和单个对象上。在大多数情况下,我们可以忽略组合对象和单个对象的差别,从而用一致的方法来处理它们。
组合模式可以使用在一下情形里:
1.表示对象的部分-整体层次结构。组合模式可以方便地构造一棵树来表示对象的部分-整体结构。特别在开发期间不确定这棵树有多少层次的时候。在树的构造最终完成, 只需要通过请求树的最顶层对象,便能对整棵树做统一的操作。在组合模式中增加和删除树的节点非常方便,并且符合开放-封闭的原则。
2.客户希望统一对待树中的所有对象。组合模式可以是客户忽略组合对象和叶对象的区别,客户不用关心当前处理的对象是组合对象还是叶对象,所以也就不用写一堆if、 else语句来分别处理它们。组合对象和叶对象会各自做自己正确的事情,这是组合模式最重要的能力。