构建具有伸缩性的JavaScript应用程序

  多人协同构建一个大型的Web应用程序是一件困难的事。很多大型的Web应用程序开发到最后变得越来越头疼,很大一部分原因是由于JavaScript的架构设计的不清晰以及不具备高扩展性。在日常的工作中寻找一些trick以及一些tip只能解决特定问题,而不能让你的架构具有伸缩性。

  将应用程序分解为多个层次,规定每层特定角色以及责任,让应用程序保持松耦合,这样的话,特定层接口被删除,修改或者替换的话对其它层的影响都是最小的。

  整个应用程序架构应该由以下几个部分组成:

  • Module
  • Sandbox
  • Core
  • Base

  我们可以在已有的JavaScript框架(jQuery, Dojo)基础上构建我们的应用程序框架。重要的一点就是把每一个页面理解成一个Module(整个web应用程序的每一个独立功能模块)。我们构建的程序不可能只有一个页面,所以会产生多个Module。所有Module都应该仅仅依赖于它们自己,目的是为了松耦合。每一个Module都应该有自己的Sandbox, Sandbox是位于应用程序核心部分(Core)的上一层。Module应该知道Sandbox,但是Module彼此之间不用关心。

  具有伸缩性的Web架构的每一个部分就类似于Puzzle游戏中的每一个Piece一样。每一个Piece不需要知道整个Puzzle有多复杂,它只要知道自己应该做什么就OK了。下面简要介绍一下每一个部分。

  Module

  Module的任务就是处理GUI与用户的交互,以及增强用户体验。这部分代码主要由JavaScript, HTML,以及CSS构成。其实整个Web应用程序就是由这些Module组合在一起工作的。

     下面是一个Module的定义样例:

Core.register("module-name", function(sandbox){
return {
init: function(){
//构造函数
},
destroy: function(){
//销毁函数
}
};
});

  Module主要关注以下几个方面:

    1. 只能调用Module内部的方法,或者Sandbox中的方法。
    2. 不要访问不是本地化的全局对象。
    3. 不要访问超出此Module管理的Box之外的DOM元素。
    4. 如果有需要访问别的什么东西的,只能调用Sandbox接口。
    5. 不要创建全局对象。
    6. 不要直接引用其他Module属性和方法。

  Sandbox 

  Sandbox是用来确保接口的一致性,因为每一个Module都了解Sandbox。  你可能不想直接通过Module来设置cookies,就交给Sandbox。由于Sandbox定义完后修改比较困难,所以应该慎重设计Sandbox。下面是一个Sandbox使用样例:

Core.register("module-name", function(sandbox){
return {
init: function(){
//这里去调用Sandbox接口
if (sandbox.enableFire()){
alert("Fire…");
}
},
destroy: function(){
//销毁函数
}
};
});

  Sandbox主要关注以下几个方面:

    1. 提供一致性接口。
    2. 确保安全。比如限制应用程序中的哪些Module能访问Sandbox,哪些不能。
    3. 提供通信。作为桥梁把Module的一些请求发送给Core的接口。

  Core

  Core就是应用程序的核心部分了,它主要用来控制应用程序。它用来初始化Module以及销毁ModuleCore用来控制Module之间的通信,一个Module的状态改变后,就需要Core通知其它与之相关的Module。创建完Module后通知Sandbox状态发生改变是一个比较好的方法。因为Sandbox能够选择是否执行Module的请求。Core也应该包含错误异常捕捉模块。

  下面是Core中控制Module部分的定义样例:

Core = function () {
var moduleData = {};
return {
register: function (moduleId, creator) {
moduleData[moduleId] = {
creator: creator,
instance: null
};
},
start: function (moduleId) {
moduleData[moduleId].instance =
moduleData[moduleId].creator(new Sandbox(this));
moduleData[moduleId].instance.init();
},
stop: function (moduleId) {
var data = moduleData[moduleId];
if (data.instance) {
data.instance.destroy();
data.instance = null;
}
}
}
} ();

  下面是Core中关于Sandbox的控制:

  

Core = function(){
return {
//.....
startAll: function(){
for (var moduleId in moduleData){
if (moduleData.hasOwnProperty(moduleId)){
this.start(moduleId);
};
}
},
stopAll: function(){
for (var moduleId in moduleData){
if (moduleData.hasOwnProperty(moduleId)){
this.stop(moduleId);
}
}
},
//....
};
}();

  注册Module应该:

Core.register("module1", function(sandbox){ /*...*/ });
Core.register("module2", function(sandbox){ /*...*/ });

  启动所有Module:

Core.startAll();


  Core 主要关注以下几个方面:

    1. 管理Module生命周期。
    2. 使得松耦合Module之间能够通信。
    3. 处理错误异常。
    4. 还要具有可扩展性

  可扩展性是非常重要的,因为在某些场景下可能需要添加一些错误处理,AJAX通信,新Module的兼容以及一些工具库。

  Base

  Core直接与Base库交互,这样的话,Base库可以调换成任何JavaScript库。

  Base主要负责以下几个方面:

    1. 浏览器标准化(消除同一接口在不同浏览器产生不同表现)。
    2. 封装一些通用的工具方法。例如解析/序列化XML,JSON,对象操作,DOM操作,AJAX通信等等。
    3. 提供低层次扩展

  这样的Web架构其实可以在多个Web应用中重用的,同时每一个Module也适合单独测试和使用,针对不同的应用只要修改Module的接口实现。获益最大的应该是构建这样架构的Web应用应该是具有高扩展性的,可以在任何时候添加删除Module

  下一篇将使用此构架构建一个Demo应用程序。

      


posted @ 2012-01-04 17:33  chinatea  阅读(360)  评论(2编辑  收藏  举报