学习WWF

 Chapter 1. Deconstructing WF

第一章 解析WF

Introductory programming texts often begin with a "Hello, World" program that prints a simple message to the standard output device. Here's that program in C#:

入门级程序设计书籍通常以在标准输出设备上打印一条简单的“Hello world”消息的程序作为开始。下面是该程序的C#版本:

using System;

class Program
{
  static void Main()
  {
    Console.WriteLine("hello, world");
  }
}

Hello, World is a popular starting point because it avoids a number of hard problems that most real-world programs need to address. Practitioners know that it doesn't take much work to expand even Hello, World to induce thorny problems rather quickly. For example, consider a simple variationlet's call it "Open, Sesame"that requires the user to enter a key before the traditional greeting is printed:

“Hello, World”程序之所以是一个受欢迎的出发点,是由于它避开了决大多数真实系统需要解决的一系列的难以处理的地方。实践者们非常清楚,即使是这种简单的“Hello, World”程序,也很容易将它扩展,引入一些难以处理的问题。例如,考虑下面一段简单的变化,我们称之为 "Open, Sesame"程序,它需要用户输入密钥后才会打印传统的欢迎信息:

using System;

class Program
{
  static void Main()
  {
    // Print the key
    string key = DateTime.Now.Millisecond.ToString();
    Console.WriteLine("here is your key: " + key);

    string s = Console.ReadLine();

    // Print the greeting if the key is provided
    if (key.Equals(s))
      Console.WriteLine("hello, world");
  }
}

The Open, Sesame console program is unremarkable in all aspects but one: Because it is dependent upon the user entering a line of text at the console, it takes an arbitrarily long period of time to complete its execution. You can compile and run the program, let it sit there for a few weeks, and then enter the key that causes it to print the expected greeting. This is by design.

这个 "Open, Sesame"程序无论怎么看都很平凡,只有一点不同:它依赖于用户在控制台输入一段文本,因此程序的执行时间是任意长的;你可以编译并运行这段程序,把它放在一边,几周后再输入密钥,它才会打印出预期的欢迎信息。这段程序就是有意这么设计的。

Open, Sesame is an example of a reactive program. A reactive program is responsive to, or indeed dependent upon, stimulus from an external entity during the course of its execution. Sometimes that external entity is a person. Sometimes that external entity is another program. Either way, reactive programs spend most of their time stuck waiting for input and therefore present challenges that are not part of the equation when writing programs like Hello, World.

"Open, Sesame"是响应式(reactive)程序的一个例子。响应式程序在其执行期间,对外部实体所做的触发(stimulus)做出响应或者说是依赖于外部实体的触发而执行。外部实体可能是人,也可能是其他程序,无论是哪种情况,响应式程序的大部分执行时间花费在等待外部输入上,因此表现出了不同的困难点,这些困难点在编写像“Hello World”的这类程序中并不存在。

Most computer programs are reactive. Software is used everywhere you look within real-world processes of all kinds: collaborative editing of documents, management of customer orders, raw materials procurement, preparation of tax returns, provisioning, administration of product development efforts, online shopping, management of customer relationships, and coordination of plant and warehouse operations. The list goes on and on. Programs in the midst of these processes need to react to input provided both by people and other programs.

大多数的计算机程序是响应式的。看看身边各种各样真实的业务过程时,你会发现软件系统无处不在:文档协同编辑,客户订单管理,原材料采购,返税申报,产品开发投入的预提与管理,在线购物,客户关系管理,以及工厂与仓库的协调操作等等。例子举不甚举。这些业务过程中的的软件程序需要对人和其他程序的输入做出响应。

Some reactive programs are developed using works such as ASP.NET and Java Servlets. Others are homegrown solutions that are built directly upon execution environments such as the Common Language Runtime (CLR) and Java Virtual Machine (JVM). Still others are written in languages like C or (unmanaged) C++.

一些响应式程序使用诸如ASP.NET,Java Servlets之类的应用框架进行开发,其他一些则是公司内部自行开发的解决方案,一般直接在诸如CLR和JVM运行环境上建构。另外一些则是用C/C++语言编写的。

However, if we look at how these reactive programs are written, we find that most are not at all like our simple Open, Sesame console program. Let's see how we can write a web service (a web application would be an equally illuminating choice) that does the same thing as our Open, Sesame console program.

然而,当我们检查这些响应式程序的编写方式时,会发现,大多数都与我们那个简单的“Open, Sesame”控制台程序大相径庭。我们来写一个ASP.NET Web service,模拟我们那个“Open, Sesame”控制台程序。

Here is a translation of Open, Sesame into an ASP.NET web service:

下面是转换的结果:

using System;
using System.Web.Services;

[WebService]
public class Service : WebService
{
  [WebMethod(EnableSession = true)]
  public string PrintKey()
  {
    string key = DateTime.Now.Millisecond.ToString();
    Session["key"] = key;
    return "here is your key: " + key;
  }

  [WebMethod(EnableSession = true)]
  public string PrintGreeting(string s)
  {
    if (Session["key"].Equals(s))
      return "hello, world";

    return null;
  }
}

This web service has two operations, and is not very complicated. However, we have entirely lost the control flow of Open, Sesamethe cold hard fact that PrintKey must occur before PrintGreeting, and that each of these steps must run exactly once in order for the program to be considered complete. To establish constraints on the ordering of its operations, we can modify the web service by adding the following code shown in boldface:

这个Web service有两个操作,并不复杂。然而,我们已经完全失去了在控制台“Open Sesame”程序里展示的控制流 - PrintKey必须在PrintGreeting操作之前执行,并且每一步操作必须运行一次并且仅仅一次,程序才算是完成。这是一个冷酷的现实。我们可以修改Web service,加入如下用粗体表示的代码,来约束这些操作的顺序执行:

using System;
using System.Web.Services;

[WebService]
public class Service : WebService
{
  [WebMethod(EnableSession = true)]
  public string PrintKey()
  {
    bool alreadyDidStep1 = (Session["key"] != null);
    if (alreadyDidStep1)
      throw new InvalidOperationException();

    string key = DateTime.Now.Millisecond.ToString();
    Session["key"] = key;
    return "here is your key: " + key;
  }

  [WebMethod(EnableSession = true)]
  public string PrintGreeting(string s)
  {
    bool didNotDoStep1Yet = (Session["key"] == null);
    if (didNotDoStep1Yet)
      throw new InvalidOperationException();

    bool alreadyDidStep2 = (Session["programDone"] != null);
    if (alreadyDidStep2)
      throw new InvalidOperationException();

    Session["programDone"] = true;

    if (Session["key"].Equals(s))
      return "hello, world";

    return null;
  }
}

 

We are now using a set of runtime checks to guarantee the correct control flow for our web service, but that logic is diffuse, implicit, and error prone. The straightforward sequencing of program statements in our Open, Sesame console program has dissolved into opaque logic that is spread throughout our web service operations. Imagine being asked to work out the control flow (not to mention the flow of data) if you are given only the web service source code. It can be done with a few seconds of code inspection for this simple example since there are only two operations, but think about doing it for a web service ten times this size, where the control flow involves branching and looping.

我们现在通过一系列运行时的检查来确保得到这个Web service正确的控制流,然而,程序逻辑混乱,不明显,并且易出错。在“Open, Sesame”控制台程序里,程序语句那种自然的顺序性,已经不复存在,溶为了分布在web service操作各处的晦涩逻辑。想象一下,如果仅给你这个web service的源码,让你去理解它的控制流(就不提它的数据流了)。在这个简单的例子里,只需浏览源代码几秒钟就能得出结论,因为它只有两个操作。但是,考虑一下一个10倍大的,包含分支与循环控制流的web service!

Why can't we use natural C# control flow constructs (we are programming in C#, after all) to specify the relationships between web service operations, and constrain what can happen when? The Open, Sesame console program has exactly the control flow and manipulation of local variables that we need for this simple program. Why is it impossible to write our web service, or a similar web applicationor just about any real-world programin this way?

那究竟为什么我们不能用C#语言里的那些自然的控制流语句去定义web service操作之间的关系,对操作的顺序进行约束呢(毕竟我们在用C#)?“Open sesame”控制台程序中的控制流以及对局部变量的操作正是所我们希望的。为什么不能以这种方式编写web service或者是类似的web应用或者任何真实世界中的应用程序?

Here are two good reasons:

以下是两个很好的理由:

In the Open, Sesame console program, Console.ReadLine blocks the caller's thread of execution. As written, the program might spend days stuck waiting for input. If many programs like this one were run simultaneously, and all were awaiting input, the system would grind to a halt. Dedicating threads in this way is not an option for real-world programs, especially those deployed in multiuser environments.

在“Open, Sesame”控制台程序里,Console.ReadLine使调用方的执行线程阻塞。如前所述,这个程序或许会停在那儿很久,等待输入。如果系统中同时有很多这样的程序运行,并且都在等待输入,那么系统会陷入宕机状态。实际的程序决不会以这种方式分配线程的使用,特别是那些部署在多用户环境中的应用。

Real-world processes take a long timedays, weeks, or even months. It is wishful thinking to assume that the operating system process (or CLR application domain) in which the program begins execution will survive for the required duration.

现实世界中业务过程的运作往往需要数天、数周甚至数月之久。认为程序执行所依赖的操作系统的进程(或CLR应用程序域)也能够持续相应的时间间隔是不现实的。

For a console program that is used for pedagogical purposes, these issues rarely worry us. As a consequence, we are able to write Open, Sesamejust like Hello, Worldin a very natural way. Reading the program code tells us exactly what the program does. But precisely the opposite is true for our web service. Scalability and robustness are usually of paramount concern when developing web services and web applications.

对于一个教学式的控制台程序,我们很少去担心这些问题。因此,我们能够像“Hello world”程序那样很自然地编写“Open sesame”程序。通过阅读程序代码就能够对程序做什么一目了然。但是我们的web service却恰恰相反。伸缩性、健壮性是开发web service和web应用程序最为关注的方面。

The ASP.NET runtime is designed to efficiently manage multiple services and applications, and can robustly maintain state for individual sessions (with the right configuration, a session can fail over from one machine to another). However, the code does not lie. The scalability and robustness benefits come at a price. In the preceding web service, the key variable that is shared by a pair of operations is manipulated as a weakly typed name- pair. Moreover, the logic that enforces appropriate ordering of operations is clumsily expressed by testing, at the beginning of each operation, whether variables such as key have been previously assigned.

ASP.NET运行环境被刻意设计能够高效地管理多个服务及应用,并且能够为各个独立的会话维护其状态(如果配置正确,会话能够在机器间保持)。然而,其代码说明了一切;伸缩性和健壮性是有代价的。在前面的web service中,不同操作所共享的key变量是通过一个弱类型的名称-值数据结构所维持的,另外,用来确保操作的正确执行顺序的逻辑,是通过在每个操作的开始处,用一个蹩脚的测试条件来约束的,如key变量是否已经被赋值。

It appears that scalability and robustness concerns are at odds with the desire to have a natural way of expressing the state and control flow of reactive programs. The fact that there are millions of web applications and web services in the world confirms that developers are willing to work within the limitations of today's programming models to get their jobs done. Even so, web paradigms are appropriate choices for only a subset of solutions requiring reactive programs. The challenge at hand is to find a better, and general-purpose, approach to developing reactive programs, web-based or otherwise. Such an approach must provide the following:

看起来似乎伸缩性、健壮性和自然地表达程序状态与控制流两者间存在冲突。现今存在的千百万的web应用程序和web service,似乎说明了开发人员愿意应用当前的编程模型去完成他们的工作,尽管这些模型存在缺陷。即便如此,web开发模式不过是响应式程序解决方案的一个合适的选择子集。目前的挑战是,发现一种更好、更通用的,开发响应式程序的方法,不管是否基于web或是其他,这种方法必须具备如下性质:

A way to write reactive programs that does not sacrifice, and in fact enriches, the natural imperative style of control flow.

一种编写响应式程序的方法,不仅不牺牲,甚至能够增强那种自然的控制流所体现的命令式风格。

A way to run reactive programs in a scalable and robust manner.

一种运行响应式程序的方法,伸缩性和健壮性俱佳。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值