用工作流方式构建应用

阅读数:2287 2009 年 6 月 14 日

话题:SOA.NET架构语言 & 开发

David Chappell 的新文章“工作流方式”开篇先讨论了编写优秀的服务器端软件有何意义:

每个编写代码的人都想构建优秀的软件。如果该软件是一个服务器应用,其优秀之处就是要伸缩良好、不用消耗太多资源就能处理大量负载。优秀的软件还应该尽可能地易于理解,无论是对创建者来说,还是对维护人员来说。同时实现这两个目标并非易事。有利于应用伸缩的设计往往会将应用拆分开,而把逻辑分散在各处会增大理解难度。反过来将逻辑统一到单一的执行单元又会使应用几乎不可能伸缩。

接着他开始讨论实现优秀服务器端软件的各种途径: 

  • 最简单的方法是创建统一的应用,在一台机器的单一进程中运行。这种实现通常要实现如下内容:
    • 维护状态,例子中用了简单的字符串变量来代表。
    • 从外界获取输入,比如从客户端接收请求。简单应用可以只从控制台读取信息,更常见的例子则可能是从 Web 浏览器接收 HTTP 请求,或从其它应用接收 SOAP 消息。
    • 向外界发送输出结果。根据应用的构建方式,应用可能会通过写到控制台或以其它方式经由 HTTP、SOAP 消息完成。
    • 使用 if/else 和 while 这些控制流语句,通过逻辑选择不同的执行路径。
    • 在应用的每个点上执行适当的代码来完成工作。
    这一简单的方法有几个优点:
    • ……能以简单、统一的方式实现逻辑。这有助于处理代码的人理解逻辑,也能清楚表明事件允许的出现顺序。
    • ……处理应用的状态很简单。状态保存在进程的内存里,而且由于进程会在工作完成之前都持续运行,所以状态总是可用的。
    这一方法的局限是:
    在应用要等待(不论是来自控制台的用户、Web Services 客户端,还是其它什么地方的)输入的时候,应用通常都会阻塞。应用使用的线程和进程在输入到达之前会一直挂起,而不管等待了多久。由于线程和进程是相对稀缺的资源,考虑到它们只是等待输入,所以持有它们的应用就不会很好地伸缩。
  • 等待输入时关闭、输入到达时重启的应用。在这种情况下,应用包含的逻辑和前面的一样,但它现在被分成了不同的块。应用接收到客户端的第一个请求时,加载和执行合适的块。一旦处理完请求并送回响应,该块就可以卸载了——内存中不用保留任何内容。客户端的第二个请求到达时,再加载、执行处理该请求的块。这种实现通常用于 Web 应用,特定页面服务于具体请求,然后应用等待下一个请求。这种架构的优点是:
    • 这种方法不会浪费资源,因为应用在不需要线程或进程的时候并不会占用它们。
    • ……让应用在不同的时间运行在不同的机器上的不同进程中。应用不会限定在单一系统……而是能在若干可用机器的任一台上执行。
    这些优势付出的代价是额外的复杂性:
    • ……代码的各个块必须以某种方式共享状态。因为每个块都是按需加载、执行、关闭,状态必须存储在外部,比如在数据库里,或是其它持久化存储。
    • ……代码不再提供程序整体逻辑的统一视图……控制流并不明显。事实上,处理客户端第二个请求的代码块可能首先要检查第一个请求是否已经被处理完。对实现了任意一种重要业务流程的应用来说,理解并正确实现跨各个块的控制流很有挑战性。
  • 基于工作流的应用。基于工作流的应用所作的事情跟普通应用一样,包括维护状态、与外界交互、控制执行流、执行应用工作。不过在工作流里,所有的这些都由活动来完成。这些活动在功能上与典型程序的各个部分相符合。它不像传统程序一样用内置的语言元素协调活动的执行,而是有一个懂得如何运行活动的工作流运行时,负责协调工作流里活动的执行。这一架构的优点是:
    • ……工作流方式给开发人员提供了统一的控制流。在简单的情况下,程序的主逻辑定义是非常连贯的。这让逻辑更容易理解……工作流本身描述了允许的控制流。
    • ……工作流不会在内存中挂起,不会阻塞线程,也不会在等待输入时耗尽进程。另一个优点是,工作流可以持久化,然后在另一台机器上再次加载。由于这个优点,工作流的不同部分可以运行在不同的系统上。
    David 所描述的工作流方法的其它优势还包括,并行工作的协调性、更高级别的重用(活动级别的重用)、流程执行的可视化 / 跟踪等。

David 文章的剩余部分描述了 Windows WF 实现的详细说明、使用场景,还有与其它.NET 技术(包括 WCF、Dublin、ASP.NET 等)的集成。他还简单说明了在.NET 4 中引入的 WF 的新特性。

尽管 David 的文章是从 Windows WF 的角度去谈如何构建工作流应用,但是按Tom Baeyens的话说:

……[文章] 解释了工作流和 BPM 引擎的本质……BPM 引擎在两个关键方面不同于 Java、C、Cobol 等普通程序:
  • 运行时状态是可持久化的。在进程执行过程中的任何时候,进程的执行都可以中断并存储。稍后可以从持久存储中取回执行状态并继续执行。
  • 图形化表示。BPM 流程与语言编写的普通程序不同的第二个方面是,BPM 流程都把方框、箭头等图形化表示作为目标。

对希望理解工作流引擎如何工作、哪些应用适合采用工作流的人来说,这是一篇很好的阅读材料。

查看英文原文:Building Applications, the Workflow Way