如何组织模型并在单页Web应用程序中实现封装

时间:2014-01-27 21:28:38

标签: javascript single-page-application module-pattern

首先,我为无知而道歉。我非常喜欢JavaScript,主要来自Java背景,所以这对我来说很新。我读了几篇文章,老实说,我不确定要问一个好问题。

我一直在关注“单页Web应用程序:JavaScript端到端”,现在我回过头来看一下代码并尝试重构/重构它,这对我来说很有意义。

我想了解的一件事是如何使用作者引用的模块化模式正确组织代码。

spa.model = (function () {
    var people,
        stateMap = { id : 1 };

    people = (function () {
        var methods1, method2;

        method1 = function(){ … }; // do something
        method2 = function(){ … }; // do something 

        return {
            method1 : method1,
            method2 : method2
        };
    }());

    return {
        people : people
    };

}());

这允许我打电话     spa.model.people.method1();

喜欢做的事情是以某种方式将people var移动到另一个文件,以便它看起来像这样

spa.model = (function () {
    var people = spa.model.people,
        stateMap = { id : 1 };

    return {
        people : people
    };

}());

spa.model.people = (function () {
    var method, method2;

    method1 = function() { return stateMap.id; },
    method2 = ... ;

    return {
        method1 : method1,
        method2 : method2
    };

}());

然而,当我像这样重构代码时,我得到各种范围错误。例如,我不能再从spa.model.people引用stateMap。

使用此模式时,如何组织更大的文件?即使只有两个对象(人和聊天),作者的spa.model文件也变得相当大。想象一下,有20个数据库对象可以建模。那将是一个巨大的档案。

2 个答案:

答案 0 :(得分:2)

IMO,最好的方法是创建父(“模型”)和从属模块,如model.people,model.auth和model.chat。父(“模型”)管理和协调共享状态和配置。下级模块(model.people,model.auth,model.chat)不应该相互调用或以其他方式依赖于其他模块。

这是一个示例,其中模型协调3个从属模块接口(model.people,model.chat,model.auth)并在其stateMap中存储共享状态。认识到每个从属模块都有自己的封装stateMap,不会污染父状态。虽然这个例子肯定不完整,但希望它有助于指明方向。

model = (function () {
  var 
    __undef,
    configMap = {};
    stateMap  = { 
      user_id   : __undef,
      chatee_id : __undef
    },

    logIn, addPerson, rmPerson, callPerson, hangUp;

  logIn = function ( user_name, passwd_str ) {
    user_id = model.auth( user_name, passwd_str );
    if ( user_id ) {
      model.people.addPerson( user_id ):
      model.chat.announceUser( user_id );
      stateMap.user_id = user_id;
    } 
  };

  // ... and more methods that coordinate subordinate modules

  return { 
    logIn      : logIn,
    addPerson  : addPerson,
    rmPerson   : rmPerson,
    callPerson : callPerson,
    hangUp     : hangUp
  };
}());

这个东西并不总是那么简单。我尽量不要对组织过于笼罩,但要牢记这一点。这有点像项目管理:我见过的唯一“完美”项目计划是在项目完成后编写的。代码组织也是如此。在我的第一次通过中,我允许自己有点草率。例如,我可能会违反no-peer-talk-talk规则作为快速破解 - 但我会添加一个很大的TODO以确保它不会生成代码。

一旦我们的代码得到解决,我就给它另一个传递并清理松散的目标 - 就像前面提到的大胖子TODO一样。结果通常是组织良好,易于理解和可维护的代码。如果没有,我会冲洗并重复。

我希望有所帮助!

答案 1 :(得分:1)

我喜欢宣布我的对象有点不同。也许你可以这样做:

(function () {

  spa.model = {

    stateMap: {
      id: 1
    },

  };


  var people = {

    method1: function() {
      return stateMap.id;
    },

    method2: function(){},
  };

  spa.model.people = people; 

  // obviously expose spa at the end.
  window.spa = spa;

}());