本书全面地介绍了软件构件技术涉及的各种问题。作者以构件与市场的关系作为入口,逐步转入对构件、接口、对象、模式、框架、体系结构等基本概念与应用的讨论。书中结合OMG、Sun和Microsoft的解决方案,介绍了构件模型与构件平台,并且在此基础之上,讲解了构件的体系结构,以及构件的发布、获取、组装等与开发过程相关的问题。最后,本书概述了软件构件技术的市场前景。全书覆盖面广,内容丰富,语言简练,并从不同的角度进行了分析、预测,是一本优秀的软件技术参考书。
本书适合从事软件设计及开发的软件开发人员、系统架构师、CTO、系统集成人员等阅读。
第1部分 动因——构件与市场
第1章 引论
1.1 构件是为组装服务的
1.2 构件——定制软件与标准软件
1.3 构件技术的必然性
1.4 软件的本质与可部署实体
1.5 构件是部署单元
1.6 经验总结
第2章 市场和技术
2.1 创造市场
2.2 构件技术的基本特征
2.3 市场发展
2.3.1 Strategic Focus(1995年1月)
2.3.2 Ovum(1995年)
2.3.3 IDC(1996年5月)
2.3.4 Forrester的研究(1996年10月)
2.3.5 IDC(1999年4月)
2.3.6 ComponentSource(2001年)
2.3.7 Flashline (2001年)
第3章 标准
3.1 (准)标准的重要性
3.2 配线标准是不够的
3.3 太多竞争标准是无用的
3.4 今天的软件构件技术在哪里
3.5 下一步该如何走
第2部分 基础
第4章 构件的定义
4.1 术语与概念
4.1.1 构件
4.1.2 对象
4.1.3 构件与对象
4.1.4 模块
4.1.5 白盒抽象、黑盒抽象与重用
4.1.6 接口
4.1.7 显式语境依赖
4.1.8 构件的规模
4.2 标准化与规范化
4.2.1 通用市场与专业市场
4.2.2 标准的构件体系与规范化
第5章 构件、接口与重入
5.1 构件与接口
5.1.1 直接接口与间接接口
5.1.2 版本
5.1.3 作为合约的接口
5.1.4 合约与非功能性需求
5.1.5 未成文的“特征”
5.2 合约内容
5.2.1 安全与进度
5.2.2 非功能性需求
5.2.3 指定时间与空间的需求
5.3 形式化与非形式化
5.4 回调与合约
5.5 回调与合约:示例
5.5.1 目录服务
5.5.2 目录服务的客户
5.5.3 客户新版本
5.5.4 违约
5.5.5 防患于未然
5.5.6 修正目录服务
5.5.7 测试函数的应用
5.6 从回调到对象
5.7 从对象间的一致性到对象重入
5.8 自干涉与对象重入:总结
5.9 进程与多线程
5.10 历史记录
5.11 规约声明
第6章 多态性
6.1 可替代性
6.2 类型、子类型和类型检查
6.3 子类型
6.4 对象语言与类型
6.5 类型、接口与构件
6.6 独立可扩展性范型
6.7 构造安全性——构件的生存力
6.7.1 模块安全性
6.7.2 模块安全性与元编程
6.7.3 多语言环境下的安全性
6.8 安全性、安全和信任
6.9 独立可扩展性的维度
6.9.1 瓶颈接口
6.9.2 单独配置
6.9.3 并行扩展、正交扩展与递归扩展
6.10 接口和合约的演化与不变性
6.10.1 合约的语法与语义变化
6.10.2 合约的有效期
6.10.3 最高法则
6.11 多态性的其他形式
第7章 对象与类组装或怎样避免继承
7.1 继承——今天的汤
7.2 在汤中加更多的香料
7.2.1 多继承
7.2.2 Mixins
7.3 回到基本因素
7.4 脆弱基类问题
7.4.1 语法脆弱基类问题
7.4.2 语义脆弱基类问题
7.5 继承——更深入的问题
7.6 受约束的继承方法
7.6.1 特化接口
7.6.2 类型化特化接口
7.6.3 特化接口的行为规约
7.6.4 重用合约和合作合约
7.6.5 表示不变式和方法精化
7.6.6 避免脆弱基类问题的受约束继承
7.6.7 创建正确的子类且不必关心超类代码
7.7 从类到对象组装
7.8 转发与代理
7.9 对代理与继承的简单回顾
第8章 构件的规模与粒度
8.1 抽象单元
8.2 计费单元
8.3 分析单元
8.4 编译单元
8.5 分发单元
8.6 部署单元
8.7 争论单元
8.8 扩展单元
8.9 错误包容单元
8.10 实例单元
8.11 安装单元
8.12 加载单元
8.13 局部化单元
8.14 维护单元
8.15 系统管理单元
8.16 小结
第9章 模式、框架和体系结构
9.1 设计级重用的形式
9.1.1 共享一致性——编程语言
9.1.2 共享具体的解决片段——库
9.1.3 共享单个的合约——接口
9.1.4 共享单个的交互片断——消息和协议
9.1.5 共享单个的交互结构——模式
9.1.6 共享体系结构——框架
9.1.7 共享总体结构——系统体系结构
9.1.8 由子系统组成的系统——框架级别
9.2 互操作性,遗产和再工程
第10章 编程
10.1 适合不同开发者的不同编程方法
10.2 为一个系统进行程序设计
10.3 面向连接的程序设计
10.4 面向连接的程序设计——更深一步的概念
10.5 事件和消息
10.5.1 消息语法和模式——XML
10.5.2 事件和调用
10.5.3 调用的语法和协议——SOAP
10.6 事件的顺序——因果条件、竞争条件和脉冲干扰
10.7 极度延迟绑定——分派接口和元编程
10.8 自由度——沙箱方法和静态安全方法
10.9 录制与脚本
第11章 其他的说法
11.1 Grady Booch (1987)
11.2 Oscar Nierstrasz和Dennis Tsichritzis(1992, 1995)
11.3 Gio Wiederhold, Peter Wegner和Stefano Ceri (1992)
11.4 Ivar Jacobson (1993)
11.5 Meta Group (1994)
11.6 Jed Harris(1995)
11.7 Ovum关于分布式对象的报告(1995)
11.8 Robert Orfali, Dan Harkey和Jeri Edwards (1995, 1996)
11.9 Johannes Sametinger(1997)
11.10 UML 1.3 Standard(1999)
11.11 Desmond D’Souza和Alan Wills (1999)
11.12 Krzysztof Czarnecki和Ulrich Eisenecker(2000)
11.13 Peter Herzum和Oliver Sims (2000)
11.14 CBSE手册(2001)
第3部分 构件模型与平台
第12章 对象和构件的“布线”标准
12.1 布线标准从何而来
12.2 从过程到对象
12.3 深层次问题
12.3.1 接口和对象引用规范
12.3.2 接口关系和多态性
12.3.3 命名和定位服务
12.3.4 复合文档
12.4 XML
12.4.1 XML、XML名字空间、XML方案
12.4.2 XML支持标准
12.4.3 XML文档对象和流模型
12.4.4 SOAP
12.4.5 XML Web服务:WSDL,UDDI,WSFL,XLANG
12.4.6 Web服务和编程模型
12.5 走哪一条路
第13章 OMG方式:CORBA, CCM, OMA 和MDA
13.1 核心——对象请求代理
13.1.1 从CORBA到OMA
13.1.2 CORBA 版本一览
13.1.3 系统对象模型(SOM)简介
13.2 公共对象服务规范(CORBA服务)
13.2.1 支持企业分布式计算的服务
13.2.2 支持细粒度对象互操作的服务
13.3 CORBA构件模型
13.3.1 可移植对象适配器
13.3.2 CCM构件
13.3.3 CCM容器
13.4 与CORBA兼容的实现
13.4.1 BEA的WebLogic
13.4.2 IBM的WebSphere
13.4.3 IONA公司的Orbix E2A应用服务器平台
13.4.4 Borland公司的企业服务器
13.4.5 非营利的实现
13.5 CORBA设施
13.6 应用对象
13.7 CORBA,UML,XML和MDA
13.7.1 元对象设施
13.7.2 模型驱动的体系结构(MDA)
第14章 SUN公司的方式——Java, Javabean,EJB和Java 2
14.1 Java构件技术的概述与历史
14.1.1 Java与Java 2
14.1.2 运行环境和参考实现
14.1.3 版本家族——微型版、标准版和企业版
14.2 Java语言
14.2.1 接口和类
14.2.2 异常和异常处理
14.2.3 线程和同步
14.2.4 垃圾回收
14.3 JavaBean
14.3.1 事件和连接
14.3.2 属性
14.3.3 自省
14.3.4 JAR文件——Java构件的打包文件
14.4 基本的Java服务
14.4.1 反射
14.4.2 对象序列化
14.4.3 Java本地接口
14.4.4 Java AWT和JFC/Swing
14.4.5 高级JavaBean规范
14.5 各种构件——Applet,Servlet,Bean和Enterprise Bean
14.5.1 Java Server Page(JSP)和Servlet
14.5.2 语境相关组装——EJB
14.5.3 数据驱动组装——EJB 2.0中的消息驱动Bean
14.6 高级Java服务
14.6.1 分布式对象模型和RMI
14.6.2 Java和CORBA
14.6.3 企业级服务接口
14.6.4 Java和XML
14.7 重新比较Java中的接口和类
14.8 JXTA和Jini
14.8.1 Jini——Java服务和客户的联合体
14.8.2 JXTA——点对点计算
14.9 Java和Web服务——SunONE
第15章 微软的方式:COM, OLE/Activex, COM+和.NET CLR
15.1 第一个基础关联模型——COM
15.2 COM对象重用
15.3 接口和多态
15.3.1 类别
15.3.2 接口和版本化
15.4 COM对象的创建和COM库
15.5 初始化对象、持久化、结构化存储、绰号(moniker)
15.6 从COM到分布式COM(DCOM)
15.7 元信息和自动化
15.8 其他COM服务
15.8.1 统一数据传输
15.8.2 分派接口和双接口
15.8.3 外出接口和可连接对象
15.9 复合文档和OLE
15.9.1 OLE容器和服务器
15.9.2 控件——从Visual Basic到OLE再到ActiveX
15.10 依赖语境的组装和服务
15.10.1 COM套间——线程和同步
15.10.2 微软事务服务器——语境和激活
15.10.3 COM+——通用化语境和数据驱动的组装
15.11 二者兼取——.NET框架
15.11.1 .NET大图景
15.11.2 通用语言基础设施
15.11.3 COM和平台的互操作
15.11.4 示范型.NET语言——C#
15.11.5 Visual Studio .NET
15.12 配件——.NET软件构件
15.13 通用语言框架
15.13.1 应用域、语境、反射及远程化
15.13.2 Windows Forms, data, management
15.13.3 Web Forms, Active Server Pages (ASP) .NET
15.13.4 XML和数据
15.13.5 Enterprise services
15.13.6 用 .NET的Web Services
第16章 进一步的技术
16.1 计算机界优异的程序设计语言扩充
16.2 日立的应用库
16.3 Groove收发器
第17章 战略上的比较
17.1 共性
17.2 不同点
17.3 为基础设施厂商做出的推论
17.4 为构件厂商所做的推断
第18章 领域标准方面的努力
18.1 OMG领域技术委员会
18.1.1 OMG商业对象领域工作组
18.2 W3C
18.3 商业过程和文档
18.3.1 OASIS和ebXML
18.3.2 RosettaNet和PIPs
18.3.3 BizTalk.org
18.4 DMTF的CIM和WBEM
18.5 Java范围内制定标准的工作
18.6 过程控制的OLE
18.7 工业协会
18.7.1 信息技术工业分组
18.7.2 商业协会
18.7.3 用户协会
第19章 当前值得关注的问题
19.1 领域标准
19.2 软件工程基础的再思考
19.3 那么它是面向对象的吗
19.4 对象的迁移性和可移动代理
19.5 基础——更好的合约,更好的构件
第4部分 构件结合体系结构和进程
第20章 构件体系结构
20.1 体系结构的角色
20.2 概念化——超越对象
20.3 关键术语的定义
20.4 分层的构件体系结构
20.5 构件和中间件
20.6 构件与生成式编程
第21章 构件框架
21.1 语境相关构件框架的贡献
21.1.1 基础与根源
21.1.2 语境相关的构件框架与连接子(Connector)
21.1.3 语境相关的构件框架与元编程
21.1.4 语境相关的构件框架与面向侧面的编程
21.2 语境相关组合框架
21.2.1 COM+语境
21.2.2 EJB容器
21.2.3 CCM容器
21.2.4 CLR语境和通道
21.2.5 元组和对象空间
21.3 黑盒构件框架
21.3.1 Carrier-rider-mapper设计模式
21.3.2 目录对象
21.3.3 层次模型视图分隔
21.3.4 容器状态
21.3.5 串联的消息多播服务
21.3.6 基于复合文档的高级应用
21.4 黑盒和OLE
21.5 Portos——一个硬实时构件框架及其IDE
21.5.1 Portos的结构
21.5.2 实时调度程序
21.5.3 交叉开发环境
第22章 构件开发
22.1 面向构件的编程方法学
22.1.1 异步问题
22.1.2 多线程
22.1.3 从电路设计中获得的经验
22.1.4 “生活”在没有实现继承的状态下
22.1.5 坚壳类
22.1.6 语言支持
22.1.7 转发语义的动态基对象
22.1.8 调用者封装
22.2 环境——选择目标框架
22.3 工具——选择编程语言
第23章 构件的分发和获取
23.1 构建能出售的——应用程序而不是构件
23.2 产品目录和描述
23.3 构件定位和选择
23.4 超级分发
23.5 中介
第24章 构件组装
24.1 构件初始化及互连
24.2 构件的可视化组装
24.3 用复合文档取代可视化组装
24.4 非图形用户界面环境的构件
24.5 可管理且“自引导的”构件组装
24.6 最终用户组装
24.7 构件演化
第25章 技术发展趋向
25.1 高级的对象组装
25.1.1 委托
25.1.2 分割对象
25.1.3 环境型获取
25.1.4 动态继承
25.2 对象和构件的抽象的新形式
25.2.1 面向主题的编程
25.2.2 面向侧面的编程
25.2.3 XML构件
第5部分 市场与构件
第26章 市场全接触
26.1 构件
26.2 构件平台和基础设施
26.3 工具
26.3.1 构件设计与实现工具
26.3.2 构件测试工具
26.3.3 构件组装工具
26.3.4 构件系统的诊断和维护
26.4 专业性服务
26.4.1 构件系统及框架的架构师
26.4.2 构件组装顾问
26.4.3 构件配置管理
26.4.4 构件库、市场与咨询
26.4.5 构件操作者、Web服务、应用服务器提供商
第27章 新职业
27.1 构件系统架构师
27.2 构件框架架构师
27.3 构件开发者
27.4 构件组装者
第28章 构件市场悖论
28.1 品牌化
28.2 为每次使用付费
28.3 和广告联合发布
28.4 对新兴市场的利用
28.5 综合力量的作用
附录A Java、C#与component Pascal的对比
词汇表
后记
(以下前言摘自本书第一版。鉴于当今世界日新月异的变化,希望读者以历史的观点看待文中所谓的“最新”的发展情况。)
软件构件的提出使得软件“部件”的重用及多应用的分批投资具有实际的可能性。重用还包括其他途径,比如代码库、设计或体系结构。因此,更精确地说,软件构件是可构成一个功能性系统且具有独立性的成品、产物、部署的二进制单元。强调独立性及二进制形式,对于多样且独立的产品提供者及集成健壮的整体系统是非常关键的。
结合使用外购及自建的构件这一新的解决方式有效地提高了产品质量,加快了发展速度,并缩短了占据市场的时间。同时,为了更迅速地适应变化需求,人们可以仅仅投入于构件系统的关键变化,而不用采取大规模的公开改动。
基于上列原因,构件被很多人认为是未来几年软件发展的基础。至少有一个明显的证据可以说明这一点:关于这个主题所发表的文章数目成指数级增长。软件构件技术是软件界最广受欢迎却知之甚少的主题之一。早在1968年,Doug McIlroy就曾预言大规模的构件生产将会解决所谓的软件危机(Naur和Randall,1969)。直到1997年软件技术成功的曙光初现,这个断言已30年悬而未决。
显然,软件构件并不仅仅是另一个流行产物——运用构件是任何成熟工程所遵循的自然准则。有时软件被认为过于易变以致构件难以生成:这并不是单纯的反对,而是指出了此准则的不成熟性。首先,构件市场还不完善因此很多构件仍需用户自己生成。在这样一个早期阶段,引入构件化软件意味着:为未来市场做好准备。
即使在前期市场阶段,构件化软件也可使软件工程得到大量好处。构件化软件要求需求、体系、设计、实现的模块化,因此构件化软件提倡将现在大型而单一的系统转化为模块化结构,后者将使我们从更好的适应性、可测性及可维护性中受益。一旦系统经过模块化设计分解生成构件,大规模的公开改动及其所导致的整个系统单调的升级工作就变得不那么必要了。
当构件市场形成时,构件化软件将显现出另一优势:投资及创新的增值效应。当然这个由结合运用购得及自建构件的方法引起的增值效应仅仅在达到关键阶段,即当可维持的市场形成时,才会产生作用。当构件数量成倍增多,自然会形成竞争性市场而且不断推动其发展,从而促使性能价格比的持续提高。但是,建立和维持市场,对于掌握构件技术来说是另一个问题,它是与构件相关的技术和经济等因素的统一体。
正是技术与商业策略的相互影响促使构件最终达到其所期望的角色。但是,鉴于技术原因,在对象产生的早期就认为它可以完全满足期望的观点是不公平的,毕竟对象已存在了相当长的一段时期,比如,可追溯至1969年的Simula对象。当今构件革命性发展的第二个推动因素是一系列重要的技术成就。最早的成就之一是1980年后期Xerox PARC和NeXT的发展。第一次成功建立市场是1992年微软Visual Basic及其组件(VBX)的推出。商业竞争促使OMG的CORBA 2.0紧随其后,在1995年中期发布。分布式及网络的持续热化促进了最新的发展,包括微软的DCOM(分布式构件对象模型)和ActiveX,Sun的Java及JavaBeans,即Java构件标准。
有一个技术性问题转变成了软件构件发展的障碍。这个问题的关键在于对一个观点普遍的错误理解,即那些具有竞争性的关键技术究竟应该产生什么作用,以及这些作用有何区别。在激烈的争论中,几乎没有出现毫无偏见的比较结论。这可以说是一个只关乎技术及其发展潜力的技术性问题。但实际上它看起来更像一个社会性问题。在很多情况下,这个问题始于对基本术语的混淆。作为三个正交的概念,分布式、对象和构件常常在各种混乱的场合组合使用。例如,分布式对象可以是,但不一定是基于构件的——而构件可以是,但不一定是支持对象或分布式的。
早期所采纳的新技术(及“标准”)一般是由非技术因素或所谓“自我实现能力”决定的。制定恰当的标准是统一各种方法并扩大构件技术基本能力的有效途径之一。不过,标准需要切实可行。类似于体能测试指标,一个紧贴构件技术实际实现的标准是很有益处的。标准就是对构件性能可使用性的规范说明,包括对其恰当性能及资源需求的明确描述。当然,至少还需要一些独立发展的构件,以真正实现所期望的互操作功能。
为了更好地理解构件化软件,必备的细节知识及必备的认识宽度是非常重要的。但是,要对此做出必要的取舍——在对构件化软件深入理解的基础上做出决断。本书是关于构件化软件及其对工程、市场和构件部署的影响,主要包括基础概念、最新技术及一系列成败经验。此外,书中还涉及了致力于构件技术发展的从业人员及他们所做的努力。
本书的目的是对构件化软件的各方面做一全面而细致的阐述,以帮助相关人员做出合理的决定,并为他们的深入研究提供起点。在介绍性说明的基础上,本书某些地方刻意加强了细节描述。不过也尽量避免了冗余的技术方法列举,取而代之的是将各种方法的相关特性汇集一起加以点评。书中所涉及的资料全面地衬托了本书主题,最简洁地覆盖了所有内容。
当今构件化软件领域有三大主流力量:对象管理组织(The Object Management Group)从商业企业的角度提出了基于CORBA的标准;Microsoft从桌面的角度提出了基于COM的标准;Sun从网络的角度提出了基于Java的标准。显而易见,企业、桌面和网络这三种解决方案最终将趋于一致。这三种标准的提供者各自都试图通过自我扩展或提供桥的连接的方式融合其他方案。这使得以上三者都存在一定弱点,而不足以承担全面鉴定解决方案的可行性的任务。本书将从战略高度比较各方法的技术性优缺点、其可能的发展趋势,以及对决策者做决定的重要意义。
实际上,本书最重要的部分并不是技术方面的,这再一次体现了构件的本质——构件只能在构件市场中发掘自身的全部潜力。技术和非技术因素间有错综复杂的关系,同时,考察两者是非常重要的。为了引导读者涉足广阔的构件化软件领域,本书的写作采用了从外入内、由内而外的方式。首先提到的是构件市场基本原理,然后通过一系列技术概念引出构件技术。在此前提下,还会谈及一些当今仍不断发展变化的构件化方法。它们未来的发展方向将会根据现在的形势做出预测。最后,以市场化的思路重现来结束讨论,并展望未来可能的发展情况。
本书面向的读者及使用说明
本书涉及的范围之广,使得它将成为所期望的读者群十分有用的背景参考资料。为了满足各类读者的需要,大部分章节相对独立,且可按照任意顺序阅读,不过我更建议按照顺序的方式。对于相关性较大的一些材料,书中给出了明确的参阅信息。另有一些跨章节的参考内容,书中会有说明,表示在后续章节将提到。跨章节的参考内容是可选的,顺序阅读者可忽略不计。
从事企业软件策略、技术更新或软件架构的专业负责人员将会从书中获益。阅读进度可根据对书中第2,第3部分所涉及内容原有的了解程度进行调整。此外,书中对各种方法优缺点的大量讨论也是非常有用的。
管理者也许只需要整体把握本书内容而从中受到启发,而不用过多地探究技术细节。他们所关注的讨论要求针对更多的因素而不仅是一项特定的技术。在这方面,本书也有助于对构件技术做出展望。对此我建议的阅读顺序是:第1部分,第2部分的第4、第8、第11章,第3部分的第12、第17章,第5部分。
开发人员同样也会从宏观角度受到启发,而他们同时也能够发现书中有许多技术细节的讨论。另外,当面对多种开发平台及构件方法时,开发人员会深刻体会到统一概念的重要性。对不同技术异同点客观的评价将对深入理解各种因素的权衡十分有益,而单纯的术语争论却不会达到这样的效果。对此我建议的阅读顺序是:第2,第3,第4部分,若需要市场方面的背景可参考第1部分的内容。
研究人员和学习高级课程的学生会在书中发现大量的实用资料。虽然本书可作为一些单元的参考阅读材料,但它并不适宜作为课本。阅读那些着重强调构件技术的单元(例如Java或ActiveX等技术)会使读者大受裨益。即使那些并非针对软件工程的单元也会使学生从中获得很多有用的信息。另外,通过学习有关高级程序设计语言的单元,学生们会增强构件领域的编程能力。对此,我建议的阅读顺序应根据特定的需要而不同:第2部分,特别是第4部分描述了基本概念;第5,第6,第7章可被进修课程或研究生课程采用。第2部分的其他章节可供选择使用。第3部分提供了大量当今技术的细节信息。第4部分则探讨了最新的发展动态。第1,第5部分也许会令学习商业课程的读者感兴趣。
声明及时间记录
我于1997年上半年完成本书的写作。对于这个日新月异、飞速发展的领域,一些材料很快就过时了。因此,我力图不过多地涉及一些显然易变的材料,而是将主要精力放在大量基础概念和方法上。尽管如此,为了使说明具体化,我还是加入了一些技术细节。我是苏黎世Oberon 微系统公司(成立于1993年)的创立者之一。该公司是第一批全力投入于构件化软件的公司中的一家。除了细致地介绍和比较各种主流产品,我也会引用Oberon微系统产品以作为前沿技术的实例进行对比说明。这其中包括构件Pascal编程语言(Component Pascal)、黑盒构件框架和制造者(the BlackBox component framework and builder),以及面向构件的实时操作系统Portos及其改善系统Denia。通过这些例子可以了解到我对它们的发展所做出的投入,以及我在高校的教学过程中对这些工具的运用。尽管有这些个人的偏爱,我还是尽量公平地对待所有涉及的方法。
本书的最终定稿要感谢那些仔细审定初稿并提出宝贵意见的人。我要特别感谢Cuno Pfister,他审阅了全部初稿及不同修改稿的部分内容并提出了大量意见和建议。对全部初稿提出修改意见的还有:Daniel Duffy,Erich Gamma,Robert Griesemer,Stephan Murer,Tobias Murer,Wolfgang Pree和Paul Roe。对部分章节提出修改意见的有:Dominik Gruntz,Wolfgang Weck和Alan Wills。另外,Marc Brandis,Bert Fitié,John Gough和Martin Odersky也提出了更深入的意见和建议。至于本书的任何错误和不当之处均由我负责。
Clemens Szyperski