js框架开发之旅--架构

这一篇我们要讨论框架的架构,并且确定我们框架的架构设计。

经过收集大家的意见反馈,我决定把这个框架取名turing.js。如果你了解阿兰·图灵,你就应该知道为什么取这个名字了,不了解的马上去查查看吧。我们的项目也算是为计算机科学史的普及做了一点儿贡献。


前期准备

这篇文章会涉及到下面一些框架的知识,如果你不了解,最好先去看看。
  •     jQuery
  •     Prototype
  •     MooTools
  •     BBC Glow


风格

不管你开发开源项目还是私有项目,你都要和别人进行协作。因此在前期明确开发目标和代码风格非常重要。
下面是我打算在项目中用到的实践准则:
  •     Verbose: 变量和方法名都是Verbose的,便于理解和查找。
  •     Portable: 跨平台,兼容不同的浏览器和控制台
  •     Explicit: 代码要容易理解
  •     Comments: 坚持写文档注释
  •     Simple: 让代码简单可读
  •     Indentation: 两空格的缩进
  •     Semicolons: 不要省略分号,这样有利于代码的压缩
  •     Quality: 通过JSLint和用户的反馈改进代码质量
  •     Testing: 首先开发测试代码
  •     Versioning: 使用GitHub进行版本控制
小牧注:Verbose风格是什么样的?我没有找到一个准确的描述,了解的请留言。

高层次的框架架构

关于js框架架构,我们的第一个问题是:如何才能自给自足?2005年Ajax流行起来,由于ajax的复杂性,我们开是追逐那些让ajax使用起来更容易的框架。到现在已经出现了服务器端的js和一些相当复杂的前端逻辑。使用一个不提供命名空间功能的js框架已经不太可能了。

最新版本的prototype.js和BBC设计的Glow都有一样的趋势就是,从原型转向了类和对象的集成。通过命名空间把类和对象都管理起来。(小牧注:本段没有遵照原文进行翻译,因为原文的表达让人难于理解,小牧通知自己的总结进行了表述)


本章所要达到的令一个目标是如何更好的兼容其他框架。我们的框架能够通过灵活的配置来实现类和对象的继承。
这个框架更像Glow,我们不会把逻辑过度封装,以便让通过这个框架学习js的人能清楚的区分浏览器相关代码和通用代码。
令一个关于Prototype的有意思的事情是通过核心的方法实现一个高层继承逻辑。它定义了 Object.extend和Class然后基于这两个功能来开发基础的功能。例如:
var Hash = Class.create(Enumerable, (function() {
  function initialize(object) {
    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  }
}


帮助函数

MooTools, jQuery和Prototype都定义了帮助函数来简化一下基础功能:
// Prototype
function $H(object) {
  return new Hash(object);
};

// MooTools
function $H(object){
  return new Hash(object);
};


给帮助函数提供一个简化接口应该是一个好的想法,但是我之前说过,我们的项目从头到尾都要让大家便于理解,即使你是一个新来的。因此,如果用简化接口的话也要保持简单和清晰。就像你使用jQuery教别人js,也得让别人知道没有了$()函数怎么操作dom元素。


初始化

许多框架都对初始化过程和元数据进行了封装。 MooTools和Prototype使用的方法有点儿类似:

var MooTools = {
  'version': '1.2.5dev',
  'build': '%build%'
};

var Prototype = {
  Version: '<%= PROTOTYPE_VERSION %>',
  ...
}

jQuery和Glow使用的方法有所不同:


(function( window, undefined ) {
  var jQuery = function( selector, context ) {
      // The jQuery object is actually just the init constructor 'enhanced'
      return new jQuery.fn.init( selector, context );
    },
    ...
    jquery: "@VERSION",
    ...
  }

  // Expose jQuery to the global object
  window.jQuery = window.$ = jQuery;
})(window);

jQuery和Glow使用匿名函数,并且作为window的属性来提供自己的接口。我们也在turing.js中使用这样的方法。


模块和插件

jQuery, MooTools和Glow在模块化方面做了很多努力。我们也采取同样的方法,使用文件的命名来划分模块,如:
  • turing.core.js
  • turing.functional.js
我们把turing作为全局变量暴露出来,我们把方法和模块作为turing的属性来定义。


让我们开始写代码

我将使用我们riot.js库写单元测试,这是一个简单的纯js的类库。
有人觉得刚起步就 开始测试代码,没有什么意义。但是我们还是要保证我们的代码在浏览器和控制台都是能正常运行的。我将要在Rhino和Firefox上运行我的代码。
测试代码要检查下面的一些点:
  • turing已经实例化
  • 我们可以读取turing的属性
测试代码如下:
Riot.context('turing.core.js', function() {
  given('the turing object', function() {
    should('be global and accessible', turing).isNotNull();
    should('return a VERSION', turing.VERSION).isNotNull();
    should('be turing complete', true).isTrue();
  });
});

我们的代码是这样的:
(function(global) {
  var turing = {
    VERSION: '0.0.1',
    lesson: 'Part 1: Library Architecture'
  };

  if (global.turing) {
    throw new Error('turing has already been defined');
  } else {
    global.turing = turing;
  }
})(typeof window === 'undefined' ? this : window);

在Rhino中的运行结果:
js> load('turing.core.js');
js> print(turing.VERSION);
0.0.1
js> print(turing.lesson);
Part 1: Library Architecture

在浏览器中查看的结果
>>> turing
Object { VERSION="0.0.1", more...}

你在github上可以获取本章的代码

alexyoung/turing.js


牧客网--让自由职业成为一个靠谱的工作


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值