http://kb.cnblogs.com/page/100177/
现在,针对移动设备像智能手机和平板电脑的应用开发很流行。Apple公司的AppStore(针对iPhone、iPod和iPad)拥有超过350,000种应用,而Android的marketplace也快速追赶上来,现在已经拥有超过200,000种应用。然而,Android和iOS并非是仅有的两种移动平台。BlackBerry也是有力的竞争者,此外还有Nokia。最近Microsoft发布了Windows Phone 7,HP也发布了新的WebOS设备。这样,对于用户来说有了多种选择,但对我们这些开发者来说却是个噩梦。我们应该针对哪种平台来开发应用程序呢?
在移动平台之间共享代码极度困难。每种平台都选择了自己的开发框架,还有自己的语言和API。对于iOS开发,你需要使用Objective-C和CocoaTouch API;对于Android开发,你要使用Java和Android API;对于Windows Phone 7,你需要使用.NET和Silverlight API。
然而,我们还是拥有一种解决方案:Web开发,特别是:Webkit。我们会看到,所有主要的移动平台供应商(除了Microsoft之外)都在Webkit之上构建了他们的移动浏览器,而Webkit是当前最新的、速度最快的开源浏览器引擎。Webkit支持多种移动应用所需要的HTML5 特性,包括侦测触摸手势(轻击、强击和缩放)、定位API(确定用户的位置),并且支持本地数据库(浏览器中的SQLite数据库,用于在本地缓存数据)。
当前,在Android、iOS、WebOS以及BlackBerry OS的六款浏览器中,都对这些特性提供了本地支持。对于不包含基于Webkit的浏览器的设备,我们还可以使用PhoneGap。PhoneGap让我们可以使用web技术(包括HTML5)开发本地应用程序,并把应用程序包装成为本地应用程序,那样就可以分发给用户了(例如,通过平台的应用程序市场)。如果平台还没有内建的WebKit浏览器,那么PhoneGap就会为其提供。PhoneGap应用程序可以在六种不同的移动平台上运行。
JavaScript框架厂商注意到了这是个机会,于是就构建了多种能够在移动Web上运行的框架。jQuery Mobile和Sencha Touch都是比较典型的例子。这些框架很容易给人留下深刻的印象,因为对于当前的开发者来说,使用它们来为移动网络开发应用程序是一种不错的方式。然而,它们还都是基于JavaScript、HTML和CSS的,它们的目的都不是要开发应用程序,而是要开发包含超链接文档的网络应用。各种框架试图对这些语言进行调整,从而适合他们的新角色,但是这会引起你的思考,专门为开发移动应用程序 而设计的语言应该是什么样子的呢?
如果我们想要设计这样的一种语言,需要解决什么样的问题呢?
我们的研究小组(软件工程研究小组,位于荷兰代尔夫特理工大学)专注于编程的转换与实现。当前,我们主要专注于领域特定语言。对于当前移动领域的开发,我们觉得有一个很好的机会,可以为移动Web开发出一种领域特定语言。我们自问:如果从头开始的话,一门专注于开发移动Web应用程序的语言,应该是什么样子的呢? 结论就是mobl。
mobl是一种文本式的、静态类型、编译的语言,主要是通过它的Eclipse插件应用。这个插件提供了语法高亮显示、内嵌的错误突出显示、引用解析以及代码自动完成。mobl编译器(集成在IDE中)会在每次保存的时候把mobl模块编译成HTML、JavaScript和CSS的组合。mobl应用程序不依赖于任何特定的服务端技术,而只会处理应用程序的客户端部分。我们可以使用AJAX的方式调用(JSON)Web服务。
mobl语言有大量特性,目的都是为了提高移动开发者的生产率:
Dynamic
类型,从而可以对Dynamic
变量的属性和方法进行任意地访问。为了真正了解mobl是什么样子的,我会在这个部分演示如何实现一个简单的to-do列表管理器。
首先我们要在Eclipse中创建一个新的mobl项目,这样会得到mobl项目的基本框架,其中有唯一的应用程序文件,我们把它命名为todo.mobl
:
这个mobl模块的第一行定义这是一个application模块。mobl有三种不同类型的模块:
application和regular模块包含任意数量的定义:用户界面、数据模型、样式、web服务接口和函数等等。
首先,让我们来使用entity
定义来定义一个数据模型。实体的实例会持久化到移动设备本身的本地数据库中。我们的to-do应用程序只需要唯一一个实体,名称为Task
。对于每个task对象,我们都希望能够记录它的名称,以及任务是否已经完成。
对于每个属性我们都会指定名称和类型,并有选择地加上一个或者多个注解。mobl支持两种类型的注解:inverse
注解(定义反向的关系)和searchable
(在全文搜索中包含字段)。尽管这个应用程序不需要,但我们还是可以指定多个实体以及它们之间的关系,包括一对一、一对多和多对多的关系。
接下来,我们对root
屏幕进行改写,从而显示我们能够勾选和取消勾选的任务列表。在mobl中,用户界面是用screen
和control
定义的。通常screen
会通过组合大量control
来定义实体屏幕布局。这样,control
会定义更小的用户界面元素,像按钮、标签和表格等等。此外,屏幕或者控件也能够定义本地状态(使用变量),并使用控件结构来对集合进行迭代,从而根据条件显示用户界面的各个部分。
下面是我们的root
屏幕的最初定义(当程序运行时所显示的第一个屏幕)。它使用了大量mobl::ui::generic
库中的控件,包括header
(渲染出屏幕的标题)、group
(对一个或者多个item
进行分组)和checkBox
。
list
控件的结构与for-each循环类似:它会遍历一个集合,对于集合中的每个项目,它都会进行渲染。checkBox
与两个Task
对象属性绑定:done
和name
。数据绑定会在应用程序状态(例如本地变量或者实体属性)和用户界面之间创造出同步的关系。例如,当用户选择复选框或者取消对它的选择时,t.done
的值就会据此更新。类似地,当应用程序的某些其他部分更新任务t
的name
属性时,复选框也会自动更新它的标签。这被叫做反应性编程(reactive programming),这也是根本的mobl特性之一:用户界面会对应用程序状态的改变做出反应。
最初时,数据库是空的,从而在我们的列表中不会显示任何任务。我们怎样才能添加任务呢? 为了这个目的,我们定义了addTask
屏幕:
使用var
结构我们可以创建嵌入在特定屏幕中的状态。在这种情况下,我们定义了变量newTask
,并使用新建的Task
实体实例对其进行初始化。我们把textField
控件与newTasks
的name
属性绑定。当用户输入完任务的名称时,他就会点击显示在应用程序标题处的Done按钮。按钮拥有名为onclick
的参数,它的值是Callback
,当事件发生的时候,就会执行一段命令式的应用程序逻辑。在这个特定的情况下,发生了两件事情:
newTask
对象。这会在后台对Task.all()
集合做出改变,使得新建的任务被自动添加到root
屏幕的list
中。screen return
和函数中的return
类似)。 然而,尽管我们定义了root
和addTask
屏幕,但没有办法从一个屏幕跳转到另一个。我们需要做的就是向root
屏幕添加一个Add按钮,它会带我们跳转到addTask
屏幕。因此,我们需要在root
中把对header
控件的调用调整为下面这样:
正如你所看到的,对屏幕的调用和对一般函数的调用类似,事实上,和函数一样,屏幕也能够返回值。
现在我们的应用程序的功能已经基本完备。我们还要添加最后一个特性:搜索。在我们的数据模型中,我们对Task
的name
属性使用了(searchable)
注解。利用,我们就可以使用搜索来过滤任务列表(从而更快地找到我们想要查找的任务)。
我们向屏幕中添加了新的本地变量phrase
,可以在其中存放查询的短语。我们使用searchBox
,并将其与phrase
绑定。然后,我们并没有遍历list
中的Task.all()
,而是遍历了搜索集合Task.searchPrefix(phrase)
。在运行的时候,当我们在搜索查询中输入内容时,搜索结果的列表就会更新。此时用户界面会再一次根据应用程序的状态(这种情况下是phrase
变量)自动调整。
现在我们已经完成了包含搜索功能的基本to-do列表应用程序的构建工作,接下来可以部署了。当我们保存mobl模块的时候,同时也会把它们编译成JavaScript、HTML和CSS,这些文件位于Eclipse项目的www/
目录下。我们可以把这些生成的文件部署到任意一个能够为静态文件提供服务的web服务器上(例如:Apache、IIS或者Tomcat),mobl完全不需要后端程序。
当然,to-do列表只是个玩具一样的例子,它只使用了一些简单的控件,像group
、item
、button
和textField
。mobl的标准库还提供了一些高级的控件,像标签组、主从视图、上下文菜单以及可扩展的列表等等。
除了定义用户界面、数据模型以及应用程序逻辑的语言结构之外,mobl还拥有以下结构:
想要了解这些特性,你可以查看mobl站点上的教程。
我们可以把mobl描述为一种领域特定语言(DSL),也就是一种针对特定应用程序领域的语言。在传统上,DSL的领域很有限。例如,HTML是一种定义结构化Web页面的DSL。SQL是用来解释数据库查询的DSL。移动应用程序的领域比上述要大得多。事实上,它非常大,以至于需要大量你通常只能在一般目的的语言或者GPL像Java、Python和Ruby中才能够找到的特性。这些典型的GPL特性包括面向对象编程、if指令和for循环等等。既然mobl拥有GPL特性,那么它还是一种DSL吗?
我们觉得是,因为它拥有语言结构,这些结构都特别地适合数据驱动的移动Web应用程序领域。例如,如果我们使用一种带有样式支持的一般目的语言,编写的是用于处理科学计算的程序,那么就不太合理了。而把screen
结构应用于服务端计算也不是很合理。像实体、屏幕、控件、样式以及Web服务等语言特性并不针对一般目的它们都是针对特定领域的。
mobl不仅仅是针对移动开发的DSL。类似的还包括Applause和由此衍生的Applitude。然而,这些DSL的灵活性都有限。它们都拥有一系列的内建控件、内建函数,一旦这些都无法满足你的需求,你就需要重新使用Objective-C或者Java来编码了。mobl的目标就是,既要灵活,又要具备较强的表达能力。
为了达到这个目的,我们让这门语言尽可能小,并且通过使用mobl本身编写库来增加功能。例如,我们用来构建to-do列表应用程序的控件都没有内建在语言之中。相反,它们都是从mobl库导入的,而这个库本身又是使用mobl定义的。在最低层级上,对控件的实现使用了低级的HTML标签和CSS样式。一般用户只会使用高级别的概念控件,像标题或者按钮等等,而专家级的开发者能够通过调整库中的底层HTML代码来精确地设计按钮的显示样式。
mobl除了能够在库中定义控件之外,它还拥有暴露了大量HTML5 API的库,包括集合定位、使用Canvas进行2D绘图以及WebSockets等等。这些库只是封装了已存在的JavaScript API,而mobl API使用mobl的本地接口,这使得它能够调用本地JavaScript代码。这样,mobl就可以通过库机制进行扩展,这让用户可以扩展平台,而不需要扩展语言和编译器本身。
在特定的情况下,mobl会为特定的库添加句法的特性。例如,对于查询,mobl暴露了Collection
类型,它拥有对实体对象的集合进行过滤、排序和分页的方法。我们可以像下面这样来调用这些方法:
很明显,这些语法有些麻烦。因此,mobl为查询添加了句法特性,让我们可以把上面的查询写成这样:
这不仅更加简洁,而且现在IDE可以检查事实上Task
是否拥有done
和date
属性,并且提供了恰当的代码自动完成功能。
mobl没有在已存在的语言基础之上构建框架,而是从头开始,构建了一种外部DSL。这种方法有优点也有缺点。缺点在于用户需要学习新语言、新库以及新的工具。优点在于,选择这种语言来进行设计,可以显著减少开发者所要编写的代码。在mobl中,我们保持它的语法与语义与JavaScript类似,从而让开发者觉得这种语言很熟悉。此外,mobl能够集成到现有的Eclipse IDE和外围工具中,提供在输入时检测错误、引用解析、代码自动完成和保存时编译等功能。
mobl还是一种很年轻的语言。第一次公开发布是在2011年1月。它的编译器、工具和文档还在逐步完善中。尽管如此,我们觉得它已经显示出在移动领域使用DSL的潜力。
英文原文:mobl: a DSL for Mobile Web Development