中间件是一些服务、协议、以及支持工具的集合,它们提供的“通道(plumbing)”使得构建现代分布式系统和应用程序成为可能,是web services、分布式对象、互相协作的应用程序、电子商务系统和其它一些重要平台下面的基础设施。不久前,中间件这个术语还很少听说,中间件开发者也几乎没有。但是在过去这十年,关于中间件的术语、研究、试验以及影响已经随处可见。然而,直到现在,还没有一本讲述怎样构建并发的面向对象的网络中间件的书,因此,此方面的设计依然像在魔法盒中一样。本书揭开了构建中间件的神秘面纱,而不需要让一个专家站在你的身后讲述充分理由的,经验主导的常见设计问题,手段,成功的解决方案和结果。
很多观点认为敲定中间件的边界是很困难的。通常,它包含了建造系统和应用程序所需要的软件,然而有时它又是操作系统内核的一部分。当你第一次在一些地方寻找的时候,你可能不会总是能一下子找到它:中间件可以出现在库、框架、操作系统以及其它的应用程序里,在java虚拟机和其它运行时系统中,在大型的软件组件里,以及像web service这样的最终产品的某些部分中。
本书不是一本讲述中间件或者那类可以用中间件设计的应用程序和分布式系统架构的课本。相反,它介绍了一种模式语言,该语言描述了在大部分中间件中都需要的通往构建面向对象通信支持的设计方法。本书中描述的很多模式在不直接基于中间件的上层和底层系统以及应用程序中都有使用。
本书注重理论上可行的解决方案。很多模式背后的基本思想对有经验的系统开发者来说很著名,例如,分配(dispatching),分离(demultiplexing),回调(callbacks),以及配置(configuration),并且有时是更多通用OO模式的变体,例如,代理(proxies),适配器(adapters),和外观(facades)。本书的主要贡献围绕在基于这些思想的深入的工程解决方案上。中间件开发者必须解决及其广泛的内容,包括吞吐量(throughput),响应能力(responsiveness),可靠性(dependability),互操作性(interoperability),可移植性(portability),扩展性(extensibility),以及容纳遗留软件(accommodating legacy software)。这些内容之间的不同(diversity)和难度(severity)说明了中间件模式的复杂性,不像在小规模OO应用程序和并发编程中那样。
大量这样的forces,与多年的软件工程经验绑定在一起,常常导致大量的设计考虑和工程选择,从它在中间件框架的表示中分离出思想。本书中使用的模式描述格式通过将解决方案描述成一系列具体的设计步骤来帮助简化这个过程。这些步骤很多都会轮流调用额外的模式。它们一起形成了模式语言,使得开发者在设计服务和应用程序的时候能够在模式之间浏览。
像作者提到的那样,本书讨论的一些思想和技术是对一些书中内容的补充,如先前的W.Ricard Setvens的关于网络编程的书(例如[Ste98])。本书的主要出发点是坚定不移的将精力集中在高级设计问题上。例如,本书解释了怎样创建一个可组合的灵活的框架-Reactor-该框架基于select()和其它操作系统调用。而不是讨论Unix的select()调用的本末。
本书的一个隐含的主题是怎样应用现代平台提供的作为构建高级框架和组件的基础的处理I/O,线程,同步,以及事件分离功能的部分功能。将重点主要放在Unix和Microsoft操作系统上的C/C++上不会妨碍这个主题。例如,Java程序员会在Java已经直接实现了本书讨论的一些模式,例如,区域锁(Scopedd Locking)的情况下,或者提供了符合模式特定实现组织框架,如可配置组件的JavaBeans框架支持的情况下,还有在一些Java不能访问底层系统机制,如同步事件分离的情况下,发现一些不重要的disconnects。
然而,更熟悉Java,Smalltalk和其它OO编程语言的读者,也会从这些模式传达的中心思想中获益,能更了解怎样以及为什么一些模式直接被语言特性和库支持,并能够基于其它模式构建有用的组件。例如,直到java.nio的出现之前,Java没有提供用来访问那些对异步I/O有用的系统结构的方法。然而,在参考了本书中描述的Proactor模式之后,我曾经用一个简单的spin-loop线程检测多个通道I/O是否可用来实现一个Java版的模拟的多路分离(demultiplexing)步骤。这虽然是低效的,但是在它预计的使用环境中很够用了。
这些年来,本书中的一些叙述,如Reactor,已经从对设计发明的描述发展成为设计模式。每个构建可移植OO中间件的人都在编写或者使用至少Wrapper Façade。但是现在包含在本书中的其它几个模式的早期描述也讨论了它们的设计的新贡献。最初有些不确定是否这些描述应该被当作模式,模式必须是经过时间的检验,独立发现的解决方案。然而,随着时间的过去,作者和OO中间件社团已经越来越确信,本书中的模式确实抓住了关键力量和设计问题的本质,并目睹了所描述的解决方案在不同的使用场景下一再的被使用。
我邀请你一起分享这个现象。通过阅读,特别是,使用本书中的材料,你会看到为什么Reactor和Proactor这样的模式名字会在OO中间件开发者之间变得如Decorator和Observer在OO GUI开发者之间那样普通。
Doug Lea
State University of New York at Oswego