Continuation,即高级程序设计抽象,常被看作是学术玩具,但是有一种新型的 Web 服务器可以让普通开发人员的生产效率更高。continuation
服务器使您能够支持浏览器中的“后退”按钮和编写风格一致的代码。世界上的开发人员公认 Seaside 是现有的顶级 continuation 服务器,但
Seaside 并不止于 continuation。
在 1999 年中期的时候,Tennessee 河水势比较低,但是 Ocoee 水势不错。当我接近一条叫做 Hell Hole
的急流时,可以看到其他的旅游者害怕得发抖,但我不担心。在这么大的筏子里,我没什么好担心的。事实上,在正前方,有个皮划艇爱好者正在里面,他的身体慢慢地向下滑,就像是一部电梯。我们通过了急流,然后他又返回,继续在里面冲浪。奇怪而美妙。
我的筏子也许更大更安全,但有些事情它就是不能做。在他的小皮划艇(叫做 playboat)里,他能够在水面下冲浪,做一些对于我们这些在筏子里面的人来说是陌生的事情。Seaside
也是如此,不会在所有的 Web 开发中都用到它,但在下面这些情况下,您也许会试一试:
- 想要一个简单的程序来管理复杂的工作流程。
- 不想使用安全、保守的语言,诸如 Java™ 程序设计语言。
- 喜欢 Smalltalk 或是一种 Smalltalk 方言。
- 公司正在起步阶段,选择一个生产效率高的技术要比选择一个运行快的技术更加重要。
本文带给您的是一次高级的 Seaside 之旅,如果您喜欢,就有足够的信息去进一步钻研。
Avi Bryant 使用 Ruby 编程语言创建了一个基于 continuation 的服务器,但是留下了 Smalltalk
的 Squeak 方言 —— 20 世纪 70 年代的初期,当 Ruby continuation 被证明是不太稳定(后来被修复)的时候,发明的一种纯面向对象的语言。然后他在
Smalltalk 的Squeak 方言上建立了 Seaside 框架并再未回头。他现在使用 Seaside 为客户快速地建立
Web 应用程序。他们愿意采用诸如 Squeak 之类的语言是因为这个框架的生产效率非常高,大大降低了开发的总成本,并提前了产品进入市场的时间。
我不是建议所有人在接下来的十年里使用 Smalltalk 进行编程。火车不用也会生锈。但我要说在经济条件限制的情况下,语言问题也就不是问题了。假如给我一个用一种晦涩的语言编写的应用程序,但它比流行的语言要快
5 倍,容易维护并且只需要现在三分之一的费用的话,我就可能不会介意您选择哪种语言。
Smalltalk 的 Squeak 方言
在深入之前,您应当了解一点儿 Squeak 语法。如果想要边看边学,请下载 Squeak 集成开发平台(参见 参考资料)。像
Squeak 之类的 Smalltalk 方言使用映像,映像是所有正在运行的程序的副本,包括上次保存 Samlltalk 映像时正在编写的类。启动
Squeak,单击 Tools,拖拽一个工作空间(workspace)和抄本(transcript)窗口到桌面。使用工作空间窗口输入,使用抄本窗口输出。
Squeak 的语法十分简单。首先键入对象名,其次是方法名,最后是所有参数。例如,在工作空间中敲入:
右键单击文本,然后选择 Do it(也可以按 Alt+d
来运行代码行)。会在 Transcript 窗口中看到单词 Hello 。Transcript
是对象,show: 是方法(Squeak 称方法为消息),Hello
是一个参数。
Squeak 支持闭包 —— 也就是,使用成块代码作为参数 —— 像这样:
1 to: 5 do: [:i | Transcript show: i]
|
开方括号和闭方括号([ 和 ] )分别标志代码块的开始和结束。i
参数标志代码块。最后,试试三段式消息,这种消息有两种结果:
age := 4.
(age > 16)
ifFalse: [Transcript show: 'Youngster.']
ifTrue: [Transcript show: 'Old timer.']
|
这个消息输出 Youngster。您要看到的所有 Squeak 暂时就是这样。您了解的东西足够可以开始学习了。
现在从 seaside.st 下载 Seaside 映像,保存到 Squeak 能够找到的地方(把它和其他的 .image 文件放到一起)。根据说明安装映像,然后启动
Web 服务器。记住:Seaside 是一个开发框架,包括基于 continuation 的 Web 服务器。Seaside 映像有一个运行版本的
Web 服务器和 continuation 框架的代码。
根据 Seaside 相应版本的说明,在浏览器中键入管理页面的路径。就我的映像来说,在浏览器中输入 http://localhost:9090/seaside/config。在提供的数据输入域中分别敲入
seaside 和 admin ,作为用户 ID 和密码,单击 Submit。
为使用 continuation,需要一个支持它们的 Web 应用程序服务器。如果您熟悉 Apache Tomcat(它处理
Java serblet)的 Java™ 技术实现,就会理解 Seaside 是一个支持 continuation
的 Squeak 的 Tomcat 实现。
Seaside 管理页面出现时,可以看到已经有一对应用程序在运行
Back 按钮支持
在管理页面,单击 Counter 应用程序。Counter 是一个简单的应用程序,它输出一个计数并包括两个链接:+ 和 -。它完全不是一个创新的程序,但很好地展示了
Seaside 的一些功能。单击 + 直到计数为 5。然后,单击 Back 两次。计数现在是 3。这是事情变得有趣的地方。您也许期望应用程序有一个会话,它的当前计数为
5。毕竟,5 是在单击 Back 前的最后一个 Count 值。单击 +:会看到计数为 4,而不是
6!
所以,Seaside 对用户来说是可预测的,而不是对编程人员是可预测的。正如您知道的那样,奇妙之处在 continuation
的字典。Seaside 每捕获一个 continuation,就将它保存在一个字典里直到一段时间过去,会话到期。Seaside
给 continuation 一个 ID 并把它放到 URL 中保存。我的 URL 是这样的:
http://localhost:9090/seaside/counter?_s=xtpbLpOxwPydFSTm&_k=RmlyloFD
|
问号后面的奇怪字符串是 continuation 的 ID。当单击 Back 两次并点击 + 一次的时候,Seaside
根据 continuation 标记载入应用程序状态,并简单地继续从那一点开始操作。也就是直接返回到一个先前的调用栈。(与 Java
语言不同,Squeak 使用动态的数据结构代替调用栈,但概念是一样的。)
让我们来看看这个程序的代码究竟是怎样的。可以从浏览器中看到。在页面的底部有几个有用的链接(参见图 2),包括一个帮助确定内存使用情况的链接、一个配置文件链接和一个管理用户会话的链接。点击
Toggle Halos 链接。
图 2. Counter 程序中的链接
注意,一个有三张图片的方框围住了所有的组件。第一张图片是一个代码编辑器,第二张是一个检查工具(用于查看系统中对象的值),第三张是一个样式编辑器(用于编辑组件的样式表)。
右击第一张图片,在新窗口中打开链接。出现了一个 Squeak 类浏览器。在第一个框中,单击 Seaside > Examples
> Test。那是模块,就像 Java 的包。在第二个框中,单击 WACounter。那是类。WA
代表 Web 应用程序。在第四个框中,会看到方法。
这四个方法的作用足够清楚了。count 方法返回当前计数,initialize
方法询问 Back 按钮支持(有些时候也许不想要 Back 按钮支持)并初始化计数值。increase
方法将 count 加 1,decrease 从 count
中减 1。单击 increase,把它改为:
increase
count _ count + 5
|
下划线指赋值。单击 Accept 并敲入您的名字首字母(为了版本控制)。返回到 Counter 应用程序并单击
+ 链接。现在它每次将计数值加 5。不需要重新载入应用程序:只要保持它一直在运行。您可能会遇到错误,那么单击 Back(恢复状态),修复错误,并继续输入。
Seaside 中的控件
现在,让我们来看看如何显示控件。返回到代码窗口,单击 RenderContentOn: 方法。出现代码:
renderContentOn: html
html heading: count.
html anchorWithAction: [self increase] text: '++'.
html space.
html anchorWithAction: [self decrease] text: '--'
|
html 参数是编写代码的地方。Seaside 提供 helper 类来帮助您显示 HTML 页面的不同部分,而不是使用模板。也可以看到链接的
helper 类。针对每种情况,传递一个代码块,它触发一个 Squeak 方法。不需要自己管理这些细节。它不像 Java 语言,但它的生产效率是非常高的。可以把组件看成
Squeak 视图。
Seaside 的好处是组件独立。可以容易地输出一个组件或一组组件。在管理页面,单击 Config 应用程序,然后单击叫做 Multi
的例子的链接。注意那 5 个计数器。单击 Show Halos,选择外圈上的浏览器图片,单击 Seaside
> Examples > Test,然后单击 WAMulti 来查看代码,如图 3 所示。只有三个方法:initialize
设置一个计数器数组,children 返回孩子列表,renderContentOn:
在五个计数器上调用 render 方法。有多少 Java Web 开发框架可以做到呢?
在 Seaside 中,每个组件必须处理它自己的状态、动作和视图。就像在 Java 语言中一样,Squeak 对象包含了大多数业务逻辑,而且
Seaside 在组件实例变量中保存了若干表示特有的状态。
到目前为止,您只看到了简单的任务。Seaside 也提供用于创建更复杂代码的任务。返回到代码浏览器(如果它不在活动状态,转到一个例子;单击
Toggle Halos 链接,单击三张图片的第一张)。现在,使用代码浏览器。在第一个列表中,选择 Seaside-Examples-Store
模块,从第二个列表中选择 WAStoreTask 类,从第四个列表中选择 Go
方法。这个 Seaside 任务处理购物车结帐。您会看到代码:
go
| shipping billing creditCard |
cart _ WAStoreCart new.
self isolate:
[[self fillCart.
self confirmContentsOfCart]
whileFalse].
self isolate:
[shipping _ self getShippingAddress.
billing _ (self useAsBillingAddress: shipping)
ifFalse: [self getBillingAddress]
ifTrue: [shipping].
creditCard _ self getPaymentInfo.
self shipTo: shipping billTo: billing payWith: creditCard].
self displayConfirmation.
|
isolate 方法允许隔离一个事务。注意那三个代码块。第一个块完成一些初始化工作,然后检索购物车的目录,并请求用户确认目录。第二个块检索发货地址和帐单地址以及信用卡信息,然后邮寄帐单。第三个块显示确认消息。可以把任务看作控制器。
注意,这里缺少状态管理。不需要把应用程序状态保存到会话或在做完的时候恢复。能够查看整个应用程序,而不是编写许多小的请求。框架以
continuation 的形式为您处理所有的状态 —— 一个非常强大的概念。
最后,Seaside 在简单老式的 Squeak 对象中处理模型。通过在第一个列表中选择 Seaside > Examples
> Store > Model 模块,可以看到这个应用程序的模型。会看到许多类,代表主要的存储模型。这没有什么特别的地方
—— 因为保存应用程序状态的代码和几个业务方法与视图无关。您得到的只是纯对象,也应该如此。
在 Seaside 中,您获得了难以置信的调试和管理工具。框架处理链接、HTML 的显示细节、状态和一些难题,比如 Back
按钮。我希望这个系列的文章能向您展示一些在 Java 语言中和 Java 语言之外进行轻量级开发的策略。在我的 Beyond
Java 一书和我先前的书(特别是 Better, Faster, Lighter Java 一书)中,您能够读到更多相关的内容。我希望您有机会尝试其中的一些技术,您的朋友将会认为它们奇怪而又美妙,就像
Ocoee 河上的皮划艇爱好者那样。
学习
- 您可以参阅本文在 developerWorks 全球站点上的
英文原文
- 轻量级开发是一个很大的课题,开发人员到处乱用这个术语以至于很难讲清楚它的意思。“轻量级开发的成功秘诀,第 1 部分:核心原理和原则”
介绍了这项技术背后的核心原理和原则。
- 重量级架构(比如 Enterprise JavaBean)对于解决日常问题来说过于复杂。“轻量级开发的成功秘诀,第 2
部分:如何减轻容器” 介绍轻量级容器并解释它们如何提供满足您业务需要的服务,又不让您受指定编程模型的束缚。
- 在 “轻量级开发的成功秘诀,第 3 部分:Spring 露出水面” 中学习一些轻量级容器的基本知识。
- 本系列的 “第 4 部分” 比较了三个流行的框架:Spring、HiveMind 和 PicoContainer。
- 轻量级开发能够很好地利用轻量级过程,但是要让一个保守的公司采用敏捷技术是很困难的。本系列的 “第 5 部分” 告诉您如何在组织内部建议并推动使用轻量级过程。
- 在“轻量级开发的成功秘诀,第 6 部分” 中,我们比较了 Enterprise JavaBean、Hibernate、Kodo
JDO 和 iBATIS 以帮助您选择最好的持久化框架。
- “轻量级开发的成功秘诀,第 7 部分:Java 替代方案” 告诉您在程序语言中什么对生产效率来说是重要的。
-
Beyond Java (作者 Bruce Tate)现在可以购买了。
-
Better, Faster, Lighter Java (作者 Bruce A. Tate 和 Justin
Gehtland)很好地概述了轻量级开发。
-
Programming Ruby (作者 Dave Thomas)是目前出版的有关 Ruby 最好的书。
- 从
Continuations Made Simple and Illustrated 获取有关 Python 语言中
continuation 的信息。
- 阅读 Martin Fowler 关于
Closure 的优秀文章。
- 了解 Smalltalk Squeak
方言。
- Seaside 是一个十分令人惊讶的框架,它基于
Samlltalk 语言和 continuation。
- 访问
developerWorks 开放源码专区 以获取更多的 how-to 信息、工具和项目更新,帮助您使用开放源码技术进行开发,并在
IBM 的产品中使用这些技术。
获得产品和技术
讨论
|