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语句来分别处理它们。组合对象和叶对象会各自做自己正确的事情,这是组合模式最重要的能力。

原文地址:https://www.cnblogs.com/xbj-2016/p/5824900.html