IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Java technology  >

诊断 Java 代码: 设计可扩展应用程序,第 3 部分

研究黑盒可扩展性在何时何地如何工作得最佳

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Eric E. Allen (eallen@cs.rice.edu), 博士研究生, Java 编程语言小组,Rice 大学

2001 年 11 月 21 日

对应于我们上一篇“ 诊断 Java 代码”中所讨论的透明盒可扩展性,黑盒可扩展性是指,在源代码既不能查看也不能修改时,可以扩展软件系统的方法。通常通过系统配置或使用特定于应用程序的脚本语言来进行这样的扩展。在本专题中,Eric Allen 讨论了何时设计黑盒可 扩展性的系统是有意义的,并提供了如何有效地实现这一设计的一些想法。阅读了本文后,您将知道何时使用黑盒并掌握如何实现它的一些技巧。请在 论坛与作者和其他读者分享您关于本文的心得。

我已在以前的文章中谈到了代码重用设计策略的重要性(主要是因为各种信息处理任务的差异和相应费用的增加),所以如果您已确定将系统可扩展性作为您的目标,那么请先问一下自己“系统的可扩展性应该达到什么程度,我能实现怎样的可扩展?”然后,考虑下列方面:

  • 对添加可扩展性的权衡,因为添加扩展性可能会降低性能或测试能力。
  • 通常,测试性最好的系统就是最简单的系统;添加可扩展性常常增加了复杂性。
  • 规划成功的可扩展设计的一个关键知识是,要知道您计划以后如何扩展系统。

在本系列的 第一篇文章中,我曾概述了系统可以呈现的可扩展性的各种形式 ― 黑盒设计与两种 白盒设计( 透明盒开放盒)。 第二篇文章中,我详细介绍了透明盒可扩展性的使用及实现,透明盒是一种恰当的介于黑盒与开放盒设计之间的设计方法。

这个月,我希望继续我们的“旅行”,展开讨论黑盒可扩展性。

在黑盒中探索方向

黑盒设计是一种可扩展性,它涉及到定制应用程序的用户配置,使该应用程序以对特定环境最有用的方式执行。当用这种方法扩展应用程序时,就不必查看原始的源代码了。

我们都使用过提供这种可扩展性的应用程序。例如,下面这两个应用程序:

  • Netscape 的插件功能
  • 在用 Emacs Lisp 配置方面,Emacs 具有无限能力

近期,几乎每个新的应用程序都提供了某种程度的黑盒可扩展性。





回页首


如何识别一个配置脚本

在继续之前,让我尝试区别配置脚本与程序的其它输入之间的不同。不幸的是,这里真的没有什么明显的差别。程序接受的一组输入(及程序解释这些输入的方法)都可以而且应该视作一种语言。但是您应该了解配置脚本的几个显著特征。

与其它程序输入(每次使用应用程序时,都可以改变程序输入)不同,配置脚本趋向于更为稳定。这些脚本一般有一些缺省值,这些缺省值最初将由用户设置,并在很长一段时间内不会重置这些值。实际上,常在最初安装程序时设置这样的脚本。更改脚本的缺省值很可能会对程序在其它输入上的行为有重大影响。而且,因为永久 存储这些输入的值,所以在随后的程序调用中会检索它们。





回页首


明智地选择配置

现在,您可能询问的下一个问题是“何时向应用程序添加这种可扩展性是有意义的呢?”

答案并非是添加尽可能多的可扩展性。毕竟,这种方法的最终结果是:给定适当的脚本(类似于 �berapplikation),单个应用程序就会执行用户所需的每个任务。

可以论证,开发环境属于这一类,但是用户/开发人员所需的“脚本”可能会非常长且复杂。这个极端示例说明了对黑盒可扩展性的基本权衡 ― 应用程序提供的黑盒可扩展性越强,用户针对特定环境而配置它所必须执行的工作就越多。

通常,最好对应用程序确定的要求范围更窄一些,但仍可以通用,然后再针对更具体的环境。正如许多“极限编程(Extreme Programming)”小组所演示的那样,缩小项目的范围很可能还会使您真正地成功完成项目(而且还是准时的!)。

某些环境需要黑盒

不过,在某些环境中,您可以非常确定其中需要某一形式的黑盒可扩展性,而且您无需使用户负担过重就能提供这一可扩展性。在许多情况下,这仍需要先实现具有较窄范围的应用程序的不可扩展版本,然后再在另一个版本中添加可扩展性。

您可能觉得这有点自相矛盾。毕竟,添加可扩展性的所有目的是减少实现系统中新功能的花费。如果知道要扩展应用程序,那为什么不在开始时就构建可扩展性呢?因为构建不具备可扩展性的应用程序通常要便捷得多。

最初您能提供的应用程序版本越简单,客户就能越快地将它用于至少是他们的部分任务中。接着,您可以从 版本 1.0的销售中获得收益,来支持开发更具可扩展性的版本。

确定复杂性

考虑这一问题的关键是,您是否希望应用程序的可扩展版本在相当大的程度上要更为复杂。有时,设计应用程序的最简单最自然的方法就是合并可扩展性。

这里最好的示例之一是税收计算应用程序。这样的应用程序可以用于许多组税单。使用哪组特定表单取决于特定的用户;因此,使用特殊用途的配置语言来描述各种表单是很自然的。如果不是这样,而将这些税单硬连接到程序中(即,通过表单的类层次结构,其中每个表单有一个单独的 类),并不会减少复杂性。

但是,一旦用黑盒可扩展性这一方法设计了应用程序,则不必修改,甚至不用查看源代码,就能够方便地添加新的表单(当下一财政年度必须这样做时)。

还有其它一些应用程序示例,它们的黑盒可扩展设计是最简单的。可以想到的示例有:Web 浏览器,电视调度查看器(类似数字电视服务使用的查看器)和依赖于公理数据库的自动化定理证明器。





回页首


值得自豪的语言

现在,假设您已决定为应用程序的某些方面提供一种配置语言。在决定这样做时,需要确认的最重要一点是:要知道您是真的在设计一种语言。必须考虑与编程语言设计者有关的相同类型的问题。例如:

  • 您的语言应该有一个正式的、定义明确的语法和语义。
  • 该语言的解释器应该包括解析器,它会拒绝除语言中语法上有效规范以外的所有内容。
  • 可能的话,应该允许进行某些与环境有关的检查,如类型检查。

请注意,这不是一个详尽的清单;还有许多其它注意事项。

某些人喜欢忽略其中一些步骤,即,不用太担心只接受语法上有效的代码。这是很普遍的。通常的结果是:很难跟踪这些语言的配置脚本中确实会突然出现的许多错误。(在我所写的“破坏者数据错误模式”一文中讨论了这一问题;请参阅 参考资料。)

遗憾的是,忽略这些步骤而产生的问题不仅仅是错误。一些最有破坏性的计算机安全性攻击(包括“红色代码(Code Red)”病毒)都是因未能正确解析输入而引起的。Ross Anderson 的 Security Engineering一书(请参阅 参考资料)包括了大量关于操作系统的环境中这样的攻击的讨论。

使用 XML 的优点

幸运的是,成功设计这样的语言已不再象以前那样困难了。XML 是用来实施这一任务的绝好工具,因为有许多现成的 XML 解析器和开发工具。

这些第三方组件不仅可以使您的工作更简便,而且还使开发人员能够更方便地将您的配置脚本重用于其它应用程序。例如,可以为药品大全应用程序编写各种分子的 XML 描述,然后可以(由无权访问原始应用程序的源代码的另一方)将这些描述重用于药品设计开发工具中。

顺便提一下,以这种方式重用代码也是必须很好定义配置语言的语义的另一个原因。如果程序的含义只能通过挖掘解释器的详细信息来确定,则重用脚本的花费会高得多。请参阅 参考资料,那里有几个非常好的 XML 工具的链接。

使用 XML 的缺点

使用 XML 存在一些缺点。用 XML 编写的脚本非常冗长,而且对某些形式的信息(如可执行代码)编码会很笨拙。同样,使用 XML 工具需要一些资源上的开销和投资,在某些情况下,这些开销和投资可能过多。在这样的情况下,我更愿意使用 S 表达式(S-expressions)作为语言的元级别(meta-level)语法。

S 表达式:XML 的替代方式

S 表达式是仅用一种形式的括号完全括起来的表达式。其名称源于编程语言 Scheme(对,“S”表示“Scheme”)。

所有 Scheme 程序都由 S 表达式构成。Scheme 和其它类似 Lisp 的语言最初都是由 AI 社区设计的,以便于由用语言本身的程序反身处理(reflective processing)语言。但是,使用 S 表达式的许多优点并不依赖于处理语言 ― 使用任何语言(包括 Java 语言)也可以简单地处理这些表达式。





回页首


待续

现在,如果您记得以下内容,源代码的可用性在实现可扩展性的过程中应该不是太大的障碍:

  • 如何识别配置脚本
  • 如何选择合适的配置
  • 如何识别哪些环境需要黑盒
  • 如何确定可扩展版本的复杂性
  • 当提供配置语言时,您实际在构建一种语言

下一次,我将演示配置语言的一个简单示例,它由 S 表达式构成,并有一个针对该语言的 Java 解释器。




参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.

  • 请参加有关本文的 论坛

  • 由 Ross J Anderson 编写的 Security Engineering: A Guide to Building Dependable Distributed Systems (John Wiley &Sons,2001)一书是一本综合设计教程,通过现实世界的系统设计的成功和失败案例来说明一些基本概念。


  • 请访问 CERT Web 站点,获取有关各种因特网的安全性攻击以及这些攻击所使用的机制的信息。


  • “万维网联盟(W3C)”提供了关于 XML信息的详尽资料。


  • alphaWorks XML 解析器(Java 版)(xml4j)是一个用 100% 纯 Java 语言编写的可进行验证的 XML 解析器,并且可用标准 Apache 许可证获得此解析器。


  • Ronald Rivest 是麻省理工学院(MIT)电子工程与计算机科学的教授,他讨论了 S 表达式及其在各种安全性应用程序中的使用,特别是在一种新的用于公用密钥基础设施的设计 ― SDSI(简单分布式安全性基础设施 (Simple Distributed Security Infrastructure))中的使用。


  • 请查看由 Krishnamurthi 等人写的“ Synthesizing Object-Oriented and Functional Design to Promote Re-Use”,获取有关“可扩展访问器模式”的更多信息。这篇论文提供了一个组合设计模式, 它综合了添加工具(函数型编程(functional programming))和扩展数据集(面向对象编程)这两种方法的最好方面。


  • 在 Gamma 等人有关“设计模式”的原作 Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley 1995)中,讨论了“标准访问器”。而 1998 年的更新版中包括了一张带有样本代码和 23 个剪贴模式的 CD。


  • Clemens Szyperski 提供了一本上乘的硬拷贝书籍, Component Software: Beyond Object-Oriented Programming (Addison-Wesley,1998),该书讲述了有关利用重用组件来设计系统方面的信息(包括对面向组件的工具和语言的研究以及对组件软件的潜力和挑战的深入讨论 )。


  • Christoph Czernohous 的两篇系列文章“ Bank on it: Introduction to J/XFS”(developerWorks,2001 年 8 月 ― 9 月)介绍并提出将“Java 平台金融服务扩展(Extensions for Financial Services for the Java platform,J/XFS)”集成到现有系统中。


  • 在“ Java 实现 XML 的主要功能”(developerWorks,1999 年 7 月)中,Todd Sundsted 演示了如何用 Java 构建一个处理 XML 的框架,以允许设计人员访问这两种语言的固有可扩展性。


  • 请阅读 Eric 的所有 Diagnosing Java Code 的文章。特别是其中一篇名为“ 破坏者数据错误模式”(2001 年 5 月)的文章, 其中论述了由毁坏的数据所造成的错误的难以捉摸的特性。


  • developerWorks Java 技术专区上,可找到更多有关 Java 方面的参考资料。


关于作者

Eric Allen 毕业于康奈尔大学,获得计算机科学和数学的学士学位。他是 Rice 大学 Java 编程语言小组的博士研究生。在回到 Rice 完成他的学位之前,Eric 是 Cycorp,Inc. 的 Java 软件首席开发人员。他还在 JavaWorld 上主持“Java 初学者”论坛。他的研究涉及在源程序和字节码层 次上的 Java 语言的语义模型和静态分析工具的开发。Eric 还帮助开发了 Rice 的 NextGen 编程语言编译器,这是一个带有一般运行时类型的 Java 语言扩展。可通过 eallen@cs.rice.edu与 Eric 联系。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款