1.3 没有框架与库的语言能怎样发展呢
1.3.1 做一个框架
聊天室接下来的发展几乎停滞了。我在RWC与RIA之争中选择了RWC,但同时也面临着RWC的困境:我找不到一个统一的框架或底层环境。因此,聊天室如果再向下发展,也只能是在代码堆上堆砌代码而已。
于是,整个2003年,我基本上都没有再碰过浏览器上的开发。2004年年初的时候,我到一家新的公司任职。这家公司的主要业务都是B/S架构上的开发,于是我提出“先做易做的1/2”的思路,打算通过提高浏览器端的开发能力,来加强公司在B/S架构开发中的竞争力。
于是我得到很丰富的资源来主持一个名为WEUI(Web Enterprise UI Component Framework)项目的开发工作。这个项目的最初设想,跟JSVPS一样是一个庞然大物(似乎我总是喜欢如图1-4所示的这类庞大的构想)。
图1-4 WEUI基本框架和技术概览
WEUI包括B/S两端的设计,甚至还有自己的一个开发环境。而它真正做起来的时候,则是从WEUI OOP Framework开始的。这是因为JavaScript语言没有真正的“面向对象编程(OOP)”的框架。
在我所收集的资料中,第一个提出OOP JavaScript概念的是Brandon Myers,他在一个名为Dynapi的开源项目工作中,提出了名为SuperClass的概念和原始代码。后来,在2001年3月,Bart Bizon按照这个思路发起了开源项目SuperClass,放在SourceForge上。这份代码维护到v1.7b。半年后,Bart Bizon放弃了SuperClass并重新发起JSClass项目,这成为JavaScript早期框架中的代表作品。
后来许多JavaScript OOP Framework都不约而同地采用了与SuperClass类同的方法—使用“语法解释器”—来解决框架问题。然而前面提到过的实现了“类Outlook界面”的Erik Arvidsson则采用了另一种思路——使用JavaScript原生代码(native code)在执行期建立框架,并将这一方法用在了另一个同样著名的项目Bindows上。
对于中国的一部分JavaScript爱好者来说,RWC时代开始于《程序员》杂志2004年第5期的一篇名为《王朝复辟还是浴火重生—The Return of Rich Client》的文章,这篇文章讲的就是Bindows(见图1-5)。
图1-5 Bindows在浏览器上的不凡表现
Bindows可能也是赶上了好时候,这一年的MS Teched就有好几个专场来讲述智能客户端(Smart Client)。而“智能客户端”的基本思想就是跨平台的、弹性的富客户端(Rich Client)。因此,“丰富的浏览器表现”立即成为“时新”的开发需求,以Bindows为代表的RWC也因此成为国内开发者和需求方共同关注的焦点。
WEUI v1.0内核的研发工作大概就结束于此时。我在这个阶段中主要负责的就是JavaScript OOP Language Core的开发,并基本完成了对JavaScript语言在OOP方面的补充。而接下来,另外两名开发人员则分别负责Application Framework与Database Layer的开发,他们的工作完成于2004年8月。紧接着,WEUI就被应用到一个商业项目的前期开发中了—WEUI很快显示出它在浏览器端的开发优势:它拥有完整的OOP框架与“基本够用”的组件库,为构建大型的浏览器端应用系统的可行性提供了实证。
WEUI在开发环境和服务器端上没有得到投入。这与JSVPS有着基本相同的原因:没有需求。于是从2004年年底开始,我就着手以UI组件库为主要目标的WEUI v2.0的开发,直到2005年3月。
1.3.2 重写框架的语言层
Qomo项目于2005年年末启动,它一开始便立意于继承和发展WEUI框架。为此,我联系了WEUI原项目组以及产品所属的公司,并获得了基于该项目开源的授权。
从WEUI到Qomo的转变之初,我只是试图整理一套有关WEUI的文档,并对WEUI内核中有关OOP的部分做一些修补。因此在这个阶段,我用了一段时间撰写公开文档来讲述JavaScript的基本技术,这包括一组名为《JavaScript面向对象的支持》的文章。而这个过程正好需要我深入地分析JavaScript对象机制的原理,以及这种原理与Qomo项目中对OOP进行补充的技术手段之间的关系。然而这个分析的过程让我汗如雨下:在此以前,我一直在用一种基于Delphi的面向对象思想的方式,来理解JavaScript中的对象系统的实现。这种方式完全忽略了JavaScript的“原型继承”系统的特性,不但弃这种优点于不顾,而且很多实现还与它背道而驰。换言之,WEUI中对于OOP的实现,不但不是对JavaScript的补充,反而是一种伤害。
于是,我决定重写WEUI框架的语言层。不过在做出这个决定时,我仍然没有意识到WEUI的内部其实还存在着非常多的问题,这其中既有设计方面的问题,也有实现方面的问题。但我已经决定在WEUI向Qomo转化的过程中,围绕这些(已显现或正潜藏着的)问题开始努力了。
Qomo Field Test 1.0发布于2006年2月中旬,它其实只包括一个$import()函数的实现,用于装载其他模块。两个月之后终于发布了beta 1版,已经包括了兼容层、名字空间,以及OOP、AOP、IOP三种程序设计框架基础。这时Qomo项目组发展到十余人,部分人员已经开始参与代码的编写和审查工作了。我得到了Zhe的有力支持,他几乎独立完成了兼容层框架以及其在Mozilla、Safari等引擎上的兼容代码。很多开源界的,或者对JavaScript方面有丰富经验的朋友对Qomo提出了他们的建议,包括我后来的同事hax等。这些过程贯穿于整个Qomo的开发过程。
在经历过两个beta之后,Qomo赶在2007年2月前发布了v1.0 final。这个版本包括了Builder系统、性能分析与测试框架,以及公共类库。此外,该版本也对组件系统的基本框架做出了设计,并发布了Qomo的产品路线图,从而让Qomo成为一个正式可用的、具有持续发展潜力的框架系统。
回顾WEUI至Qomo的发展历程,后者不单单是前者的一个修改版本,而几乎是在相同概念模型上的、完全不同的技术实现。Qomo摒弃了对特殊的或具体语言环境相关特性的依赖,更加深刻地反映了JavaScript语言自身的能力。不但在结构上与风格上更为规范,而且在代码的实用性上也有了更大的突破。即使不讨论这些(看起来有些像宣传词)因素,仅以我个人而言,正是在Qomo项目的发展过程中,加深了对JavaScript的函数式、动态语言特性的理解,也渐而渐之地丰富了本书的内容。
1.3.3 富浏览器端开发(RWC)与AJAX
事情很快发生了变化—起码,看起来时代已经变了。因为从2005年开始,几乎整个B/S开发界都在热情地追捧一个名词:AJAX。
AJAX中的“J”就是指JavaScript,它明确地指出这是一种基于JavaScript语言实现的技术框架。但事实上它很简单—如果你发现它的真相不过是“使用一个对象的方法而已”,那么你可能会不屑一顾。因为如果在C++、Java或Delphi中,有人提出一个名词/概念(例如Biby),说“这是如何使用一个对象的技术”,那绝不可能得到如AJAX般的待遇。
然而,就是这种“教你如何使用一个对象”的技术在2005年至2006年之间突然风行全球。Google基于AJAX构建了Gmail;微软基于AJAX提出了Atlas;Yahoo发布了YUI(Yahoo!User Interface);IBM则基于Eclipse中的WTP(Web Tools Project)发布了ATF(AJAX Toolkit Framework)……一夜之间,原本在技术上对立或者竞争的公司都不约而同地站到了一起:它们不得不面对这种新技术给互联网带来的巨大机会。
事实上,在AJAX出现的早期,就有人注意到这种技术的本质不过是同步执行。而“同步执行”其实在AJAX出现之前就已经应用得很广泛了:在Internet Explorer等浏览器上采用“内嵌帧(IFrame)”载入并执行代码;在Netscape等不支持IFrame技术的浏览器中采用“层(Layer)”来载入并执行代码。这其中还有JSRS(JavaScript Remote Scripting),它的第一个版本发布于2000年8月。
但是以类似用JSRS的技术来实现的HTTP-RPC方案存在两个问题:
■ IFRAME/LAYER标签在浏览器中没有得到广泛支持,也不被W3C标准所认可。
■ HTTP-RPC没有提出数据层的定义和传输层的确切实施方案,而是采用B/S两端应用自行约定协议的方式。
然而这仍然只是表面现象。JSRS一类的技术方案存在先天的不足:它仅仅是技术方案。JSRS并不是应用框架,也没有任何商业化公司去推动这种技术。而AJAX一开始就是具有成熟商业应用模式的框架,而且许多公司快速地响应了这种技术并基于它创建了各自“同步执行”的解决方案和编程模型。因此真正使AJAX浮出水面的并不是“一个XMLHttpRequest对象的使用方法”,也并不因为它是“一种同步和异步载入远程代码与数据的技术”,而是框架和商业标准所带来的推动力量。
这时人们似乎已经忘记了RWC。而W3C却回到了这个技术名词上,并在三个主要方面对RWC展开了标准化的工作:
■ 复合文档格式(Compound Document Formats,CDF)。
■ Web标准应用程序接口(Web API)。
■ Web标准应用程序格式(Web Application Format)。
这其中,CDF是对AJAX中的“X”(即XML)提出标准;而Web API则试图对“J”(即JavaScript)提出标准。所以事实上,无论业界如何渲染AJAX或者其他的技术模型或框架,Web上的技术发展方向,仍然会落足到“算法+结构”这样的模式上。这种模式在浏览器上的表现,后者是由XML/XHTML标准化来实现的,而前者就是由JavaScript语言来驱动的。
微软当然不会错过这样的机会。微软开始意识到,Flash已经成为“基于浏览器的操作平台”这一发展方向上不可忽视的障碍,因此一方面发展Altas项目,用.NET Framework+ASP.NET+VS.NET这个解决方案解决RWC开发中的现实问题,一方面启动被称为“Flash杀手”的Silverlight项目对抗Adobe在企业级、门户级富客户端开发中推广RIA思想。
此时,基于虚拟机而不是直接编译到native的方式已经成了执行环境的主流,因此编程语言体系也开始发生根本性的动摇。Adobe购得Macromedia之后,把基于JavaScript规范的ActionScript回馈给开源界,与Mozilla开始联手打造JavaScript 2;SUN在Java 6的JSR-223中直接嵌入来自Mozilla的Rhino JavaScript引擎,随后Java自己也开源了。在另一边,微软借助.NET虚拟执行环境在动态执行上天生的优势,全力推动DLR(Dynamic Language Runtime),其中包括Ruby、Python、JavaScript、VB等多种具有动态的、函数式特性的语言实现,这使得.NET Framework一路冲进了动态语言开发领域的角斗场。