首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

用 continuation 开发复杂的 Web 应用程序(1)

用 continuation 开发复杂的 Web 应用程序(1)

由于 HTTP 天生的无状态性质,Web 技术遇到了这样一个问题:在两个连续的用户交互之间会遗忘状态信息。一个交互性的 Web 应用程序由一组脚本构成,每个交互都包含两个脚本,一个脚本向浏览器递交页面(然后结束),用户及时完成并提交表单,然后另一个(可能是不同的)脚本处理提交的表单。所以,应用程序逻辑分布在多个脚本之间。
由于浏览器还允许用户在交互中回溯,或者克隆一个正在处理中的交互过程,之后并行执行这两个交互过程,所以问题变得更加复杂。因为有这些可能,用户可以在任意时间在应用程序中能找到多条导航路径,所以您必须编写代码才能保证每个输出都成功。Web 开发框架(例如 Spring 和 Struts)允许您处理多条导航路径,但是它们做到这点的代价是:进一步提高了整体上已经很复杂的代码库(code base)的复杂性。
在本文中,我将介绍一个基于 continuation 的备选方案,该方案可以简化复杂 Web 应用程序的开发。我将从介绍 continuation 开始,讨论基于 continuation 的技术如何能够成为传统的 MVC 编程风格的有力武器。然后,我将转到一个简单的示例:一个企业应用程序,用它演示使用 continuation 在简化开发和使应用程序代码更容易理解方面的优势。因为使用 continuation 主要的不足之一是 Java 平台上缺少对它的支持,所以我采用 Apache Cocoon 框架来演示用 JavaScript 实现的示例程序,以及一个纯 Java 语言的实现。最后,我用对 continuation 优势与不足的进行概述,以此结束本文。
请选择本文顶部或底部的
Code图标下载示例应用程序的源代码。请参阅
,下载 Apache Cocoon 框架,运行示例需要这个框架。

到底什么是 continuation ?传统上,
continuation(继续)被定义为一个函数,它代表 "计算剩余的部分" 或者 "接下来要做的事"。换句话说,把中间结果(由前面的运算生成)发送给 continuation,会产生整体运算的最终结果。

例如,请看下面这个很基本的 Java 方法,它返回传给它的整数的平方:
清单 1. 计算整数输入平方值的方法
1
2
3
4
public static int computeSquare(int x)
{
    return (x*x);
}




这个方法返回一个值,但是没有明确指定返回值的位置。而使用得当的 continuation 会明确指定返回的位置。
这样,假设我修改了以上方法(以及系统中的每个方法),在方法中包含了一个代表 continuation 的额外参数。通常,该参数应该是跟在方法中所有其他参数后面的最后一个参数。在调用函数时,它像以前那样执行内部逻辑,区别仅在于
返回的输出值,函数会把该值传递给 continuation,要求继续进行计算,从而利用输出的值
继续。这样,上面的方法就会重写,如清单 2 所示:

清单 2. 用 continuation 对象重写后的方法
1
2
3
4
public static int computeSquare(int x, Continuation c)
{
    c.evaluate(x*x);
}




高阶函数请注意在清单 2 的示例中,函数computeSquare实际上是一个高阶函数,因为它用函子(functor)对象(Continuation对象,
c)作为参数,并用
x*x计算生成的中间结果向函子的
evaluate方法发送消息。

这种编程风格(不允许函数返回值)叫做
继续传递风格(Continuation Passing Style),或 CPS。函数
f1通过把应当返回的值传递给必须显式地传递给它的 continuation 函数,模拟了返回操作。同样,如果
f1在中间需要调用第二个函数
f2,那么它必须向
f2传递一个代表 "
f1剩余部分" 的 continuation(与剩余的参数一起)。一旦
f2完成,那么代表 "f1剩余部分"的 continuation 会用
f2的计算结果继续进行计算。

现在,为了添加一点花样,我要引入另一个函数
f3,它在
f2的尾部被调用。如果
f2要照着
f1的方式做,传递它的 continuation,那么它最后只会把
f1的 continuation 传递给
f3。一旦已经执行了
f3,所要做的所有其余操作将是继续执行
f1的 continuation。

换种方式说,所谓
continuation就是保存下来的程序在指定时间点上的执行状态快照。有可能恢复这个状态,并从这一点起重新开始程序的执行,就像堆栈追踪,所有的本地变量以及程序的计数器都能重新找回自己原来的值。请参阅
,学习更多有关 continuation 的内容。现在我要把重点放在向您演示 continuation 在减少复杂 Web 应用程序上投入的编程精力方面能做些什么。在我们进入这个话题之前,请让我先花点时间进一步解释我要解决的问题。
返回列表