【问题标题】:What is the benefit of this pattern: loos augmentation这种模式有什么好处:失去增强
【发布时间】:2014-04-14 10:27:10
【问题描述】:

所以,我需要一个单身人士。它确实是一个相当大的“做某事”对象。处理信息等。它可以扩展,一些方法可以甚至可能被继承,但总的来说,不需要存在多个。所以,我在这里读了一些我喜欢这个概念的东西:http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

我更多地考虑利用子模块的行为。

但是,我想将我的 obj 分解为子模块。但我没有看到需要传入父子模块,因为该父子模块的“返回”无论如何都会让我访问。翼。也许我在这里错过了“稳健性”或实际用法。

例如。

var a = {};

a.m = function(){

    var conf = {
        a: 'aaa',
        b: 'bbb'
    }

    var funcs = {
        func1: function(){
            console.log('a.m sub object func1');
        }

    }
    return {  // doing this gives me access
       conf: conf,
       funcs: funcs
    };
}()

// this sub module obj WILL need some behaviors/methods/vals in a.m
a.anothersub = (function(m){

   var anotherSub = m;
   anotherSub.funcs.func1(); // access to a.m methods do I even need to pass it in?
   a.m.funcs.func1();  // also access to a.m methods

}( a.m || {}))

// is a better approach to extend a.anothersub with a.m? 
// jQuery.extend(a.anothersub, a.m);

如果“m”和“anothersub”都是对象“a”的一部分。这里是否需要松散或紧密的扩充,并且为了保持代码分隔和相同的功能行为,我正在创建这些“子对象”。

我读了那篇文章,觉得我可以利用它的力量。但不确定这是这里最好的方法,甚至需要。你的想法?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    这一切都取决于您的模块/子模块实际上的紧密耦合程度,以及您可以期望它们在您的应用程序周围的所有地方存在多少(即:网站的每个页面,或在应用程序等)。

    它还提出了几个不同的主题。
    第一个可能是关注点的分离,另一个可能是依赖倒置,而另一个与两者相关的可能是代码组织/分发。

    另外,这取决于两个子模块的内聚程度......

    如果你有类似的东西:

    game.playerFactory = (function () {
        return {
            makePlayer : function () { /*...*/ }
        };
    }());
    
    game.playerManager = (function (factory) { return {/*...*/}; }(game.playerFactory));
    

    将工厂作为参数传递给管理器可能是有意义的。 那时,将两者都附加到 game 确实只是一个方便的地方,可以让它们都可以在全局范围内访问。

    但是,从一个或另一个内部调用 game 是有问题的,在大型系统、具有大量子模块的系统或接口仍在不断变化的系统中(什么时候不是?)。

    // input-manager.js
    game.inputManager = (function () {
        var jumpKey = game.playerManager.players.player1.inputConfig.jump;
    }());
    

    如果您的所有按钮都以这种方式映射并绑定到每个玩家的每个按钮,那么突然之间,您就有了 40 行紧密绑定的代码:

    1. game 的全局名称
    2. playerManager的模块名称
    3. playerManager (playerManager.players.player1) 的模块接口
    4. player (player.inputConfig.jump) 的模块接口

    如果其中任何一项发生了变化,那么整个子模块就会中断。
    输入管理器真正应该关心的唯一一个是具有.inputConfig 接口的对象。
    在这种情况下,这是一个player 对象... ...在另一种情况下,它可能完全解耦或卡在另一个接口上。
    你可能在实现一个巨大的模块的过程中发现它应该是六个更小的模块。

    如果你一直在传递你的对象,那么你真的只需要改变你传递的内容:

    game.inputManager = (function (hasInput) {
        var jumpKey = hasInput.inputConfig.jump;
    }(game.playerManager.players.player1));
    

    很容易变成

    game.inputManager = function (hasInput) {
        /*...*/
    }(game.playerManager.getPlayer("BobTheFantastic").config));
    

    并且只更改了一行代码,而不是引用game. ......的每一行

    对于实际的全局引用也可以这样说:

    // my-awesome-game.js
    (function (ns, root) {
        root[ns] = { };
    }( "MyAwesomeGame", window ));
    
    // player-factory.js
    (function (ns, root) {
        root[ns] = {
            make : function () { /*...*/ }
        };
    }("playerFactory", MyAwesomeGame));
    
    // player-manager.js
    (function (ns, root, player) {
        var manager = {
            players : [],
            addPlayer : function () { manager.players.push(player.make()); }
        };
    }("playerManager", MyAwesomeGame, MyAwesomeGame.playerManager));
    

    您的代码并非无法更改,但您已经所做的是根据外部更改最小化任何一个子模块需要进行的更改量。

    这也直接适用于增强。

    如果您需要在完全不同的文件中覆盖某些软件的某些部分,页面下方的 20,000 行代码,您不希望遭受与在其他地方更改接口相同的命运...

    (function (override, character) {
        override.jump = character.die;
    }( MyAwesomeGame.playerManager.get(0), MyAwesomeGame.playerManager.get(1) ));
    

    现在,每次玩家 1 尝试跳跃时,玩家 2 都会死亡。
    极好的。

    如果游戏界面在未来发生变化,只需改变实际的外部调用,一切就可以继续工作。
    更好。

    【讨论】:

    • 感谢 Norquard - 这个想法是初始模块“a.m”,它包含很多螺母和螺栓。我计划有几个子模块......阿拉...... a.doesthis,a.doesthat等......这些更像是单一的辅助项目。所以,我试图找出能够使用它们的最佳行动方案,并让它们将方法调用到“主子”、“a.m”中,这有意义吗?
    • @jamesemanon 确实如此。模式并没有真正改变。您应该问的是,您的小包是否属于 a.m 的子级,或者作为 a.m 的兄弟姐妹,将 a.m 注入到它们的模块中以用于 DI 目的,或者这些代码块是否甚至需要公开访问。如果他们是兄弟姐妹,则附加到根/等等。如果您将子模块附加到a.m,那么当您导入function(mod) { mod.sub = { }; }(a.m) 时,如果它们只需要初始化,请调用您需要的任何内容,然后返回。
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多