JavaScript设计模式笔记(六)组合模式

本文深入探讨了组合模式的概念,通过树形结构表示“部分-整体”的层次结构,展示了如何使用组合模式处理宏命令,并分析了其优缺点。文章还强调了组合模式与IS-A和HAS-A关系的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

组合模式的定义

组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。

曾探《JavaScript设计模式与开发实践》

组合模式用于处理组合对象的请求。

更强大的宏命令

关于宏命令的实现,我在命令模式的笔记中已经提及了。

在组合模式中,可以对宏命令做更好的处理,将一些小的宏命令合成大的宏命令,下面引用《JavaScript设计模式与开发实践》的代码来说明这点。

<html>

<body>
    <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 = MacroCommand();
        macroCommand1.add(openTvCommand);
        macroCommand1.add(openSoundCommand);

        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);
    </script>
</body>

</html>

结果

这里的命令发出是以链式的方法发出的,一个大的宏命令告知其包含的命令执行execute方法,若其中还有宏命令,则继续告知,若为普通命令,则直接执行execute方法。

该例子的树形结构为

组合模式的注意点

1.组合模式不是父子关系

组合模式是一种HAS-A的关系,而不是IS-A的关系。

HAS-A:一种事物为另一种事物上的一个部件

IS-A:一种事物为另一种事物中的一种分类

组合对象包含一组叶对象,方法的真正执行是在叶对象上,其他对象方法的执行实际上起到了一个命令传递的作用。

2.命令方法的一致性

要保证对象能从根一直传递到叶,必须保证方法名是相同的,如上面例子中都是execute。

3.一个对象不能有两个“父对象”

这里的“父对象”指将命令传给该对象的对象,如果一个对象有两个“父对象”,意味着在命令传递过程中,它的方法会被执行两次,假如它不是叶对象,其下的所有对象的方法都会被执行两次。

组合模式的优点

1.对于树中的对象“平等”对待

不管树中的对象是组合对象或者叶节点对象,都执行相同的方法

2.迭代树关系数据的便利性

只需要执行根节点的方法就可以对整棵树执行该方法,对迭代一棵树来说很方便

组合模式的缺点

1.树结构中对象的相似性过高

为了保证树结构中的节点能被遍历,每个节点的方法大都是相同的,这样在看代码时很难区分对象,只有在执行的时候才能区分对象

2.创建过多的对象

组合模式除了为每一个执行方法的对象构建一个对象,还要构建多个组合对象来构成最后完整的树结构,在这个过程中可能会构建过多的对象,而系统可能担负不起过多的对象。


参考自曾探的《JavaScript设计模式与开发实践》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值