这种模式的好处是什么:loos augmentation

时间:2014-04-12 21:59:06

标签: javascript jquery

所以,我需要一个单身人士。它确实是一个相当大的“做某事”的对象。处理信息等。它可以扩展,有些方法甚至可以继承,但总的来说,不需要存在多个方法。所以,我在这里读了一些我喜欢这个概念: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'的一部分。这里是否需要松散或严格的扩充,为了保持代码划分和相同的功能行为,我正在创建这些“子对象”。

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

1 个答案:

答案 0 :(得分: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; }()); 是有问题的。 / p>

game

如果所有按钮都以这种方式映射并绑定,对于每个玩家的每个按钮,那么突然间你就会有40行代码非常紧密地绑定到:

  1. 全球名称playerManager
  2. playerManager
  3. 的模块名称
  4. playerManager.players.player1player
  5. 的模块界面
  6. player.inputConfig.jump.inputConfig
  7. 的模块界面

    如果这些事情中的任何一个发生变化,那么整个子模块就会中断 输入管理器应该关注的唯一一个是具有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));

    的每一行

    对于实际的全球参考也是如此:

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

    您的代码不会受到更改的影响,但您已经完成的工作是根据外部更改最小化任何一个子模块需要进行的更改量。

    这也直接适用于扩充。

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

    {{1}}

    现在,每当玩家1试图跳跃时,玩家2就会死亡 太棒了。

    如果游戏界面将来发生变化,只有实际的外部呼叫必须改变,以便一切都能继续工作。
    更好。