标题:
用 continuation 开发复杂的 Web 应用程序(1)
[打印本页]
作者:
look_wt
时间:
2018-10-15 18:29
标题:
用 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 应用程序上投入的编程精力方面能做些什么。在我们进入这个话题之前,请让我先花点时间进一步解释我要解决的问题。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0