UML软件工程组织

 

 

轻量级开发的成功秘诀,第 8 部分: Seaside
 
作者:Bruce Tate 出处:IBM
 
本文内容包括:
Continuation,即高级程序设计抽象,常被看作是学术玩具,但是有一种新型的 Web 服务器可以让普通开发人员的生产效率更高。continuation 服务器使您能够支持浏览器中的“后退”按钮和编写风格一致的代码。世界上的开发人员公认 Seaside 是现有的顶级 continuation 服务器,但 Seaside 并不止于 continuation。

在 1999 年中期的时候,Tennessee 河水势比较低,但是 Ocoee 水势不错。当我接近一条叫做 Hell Hole 的急流时,可以看到其他的旅游者害怕得发抖,但我不担心。在这么大的筏子里,我没什么好担心的。事实上,在正前方,有个皮划艇爱好者正在里面,他的身体慢慢地向下滑,就像是一部电梯。我们通过了急流,然后他又返回,继续在里面冲浪。奇怪而美妙。

我的筏子也许更大更安全,但有些事情它就是不能做。在他的小皮划艇(叫做 playboat)里,他能够在水面下冲浪,做一些对于我们这些在筏子里面的人来说是陌生的事情。Seaside 也是如此,不会在所有的 Web 开发中都用到它,但在下面这些情况下,您也许会试一试:

  • 想要一个简单的程序来管理复杂的工作流程。
  • 不想使用安全、保守的语言,诸如 Java™ 程序设计语言。
  • 喜欢 Smalltalk 或是一种 Smalltalk 方言。
  • 公司正在起步阶段,选择一个生产效率高的技术要比选择一个运行快的技术更加重要。

本文带给您的是一次高级的 Seaside 之旅,如果您喜欢,就有足够的信息去进一步钻研。

用 Smalltalk 编程?

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 的语法十分简单。首先键入对象名,其次是方法名,最后是所有参数。例如,在工作空间中敲入:

Transcript show: 'Hello'

右键单击文本,然后选择 Do it(也可以按 Alt+d 来运行代码行)。会在 Transcript 窗口中看到单词 HelloTranscript 是对象,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 框架中工作

现在从 seaside.st 下载 Seaside 映像,保存到 Squeak 能够找到的地方(把它和其他的 .image 文件放到一起)。根据说明安装映像,然后启动 Web 服务器。记住:Seaside 是一个开发框架,包括基于 continuation 的 Web 服务器。Seaside 映像有一个运行版本的 Web 服务器和 continuation 框架的代码。

根据 Seaside 相应版本的说明,在浏览器中键入管理页面的路径。就我的映像来说,在浏览器中输入 http://localhost:9090/seaside/config。在提供的数据输入域中分别敲入 seasideadmin,作为用户 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 程序中的链接
Counter 程序中的链接

注意,一个有三张图片的方框围住了所有的组件。第一张图片是一个代码编辑器,第二张是一个检查工具(用于查看系统中对象的值),第三张是一个样式编辑器(用于编辑组件的样式表)。

右击第一张图片,在新窗口中打开链接。出现了一个 Squeak 类浏览器。在第一个框中,单击 Seaside > Examples > Test。那是模块,就像 Java 的包。在第二个框中,单击 WACounter。那是类。WA 代表 Web 应用程序。在第四个框中,会看到方法。

这四个方法的作用足够清楚了。count 方法返回当前计数,initialize 方法询问 Back 按钮支持(有些时候也许不想要 Back 按钮支持)并初始化计数值。increase 方法将 count加 1,decreasecount 中减 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 结构

在 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 的力量

在 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 的产品中使用这些技术。
获得产品和技术 讨论
 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号