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

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

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

对添加可扩展性的权衡,因为添加扩展性可能会降低性能或测试能力。

通常,测试性最好的系统就是最简单的系统;添加可扩展性常常增加了复杂性。

规划成功的可扩展设计的一个关键知识是,要知道您计划以后如何扩展系统。

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

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

在黑盒中探索方向

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

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

Netscape 的插件功能

在用 Emacs Lisp 配置方面,Emacs 具有无限能力

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

如何识别一个配置脚本

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

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

明智地选择配置

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

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

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

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

时间: 2024-09-23 04:27:23

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

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

玻璃箱可扩展性是指这样一种方式:软件系统可在源代码可以查看而不可以修改时被扩展 ― 它是黑箱设计(在这里构建扩展时,不查看原始代码)和开放箱设计(扩展代码直接写入到基础代码)的折衷.因为新的扩展直接建立在原始代码基础上,但不改动原始代码,所以,玻璃箱设计或许是扩展一个软件系统最有效.最安全的方法.在 诊断 Java 代码的这一部分中,Eric Allen 详述了上个月谈及的玻璃箱可扩展性主题.读完本文后,您将知道什么时候使用玻璃箱,并将获得一些如何实现它的提示. 随着信息处理任务(和与之相关的成

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

在 上个月的专栏文章中,如果您掌握以下几点的话,那么您会明白,底层代码的可用性不会成为问题: 如何识别配置脚本 如何选择允许哪种配置 识别哪种环境要求黑箱可扩展性 衡量可扩展性所带来的构建复杂性 当提供此扩展性给配置脚本时,您 实际上正在构建一种语言. 您还认识到,考虑到应用程序的黑箱可扩展性,使用 S-expression 是一种快速建立一种配置语言的有效手段.我们将在本文深入研究 S-expression,并提供了一个如何用这些 S-expression 来快速方便地为特定应用程序建立配置语

诊断Java代码

诊断Java代码: Broken Dispatch错误模式 诊断Java代码: Double Descent错误模式 诊断Java代码: Impostor Type错误模式 诊断Java代码: Java编程中的断言和时态逻辑 诊断Java代码: Liar View错误模式 诊断Java代码: Repl提供交互式评价 诊断Java代码: 单元测试与自动化代码分析协同工作 诊断Java代码: 将时态逻辑用于错误模式 诊断Java代码: 进行记录器测试以正确调用方法 诊断Java代码: 空标志错误模式

诊断Java代码: 进行记录器测试以正确调用方法

用 JUnit进行单元测试是一个功能强大的方法,它可以确保您的代码基础的完整性,但是一些不变量比其他(方法调用序列是其中一种)更难测试.在诊断Java 代码这一部分,Eric Allen描述了怎样在您的单元测试中使用记录器(一种特殊的侦听器),来确保一个方法调用序列按恰当的顺序发生.请点击文章顶部和底部的 讨论,与作者和其他读者在论坛上分享您关于本文的看法. 随着时间的推移,当系统开发人员,维护人员甚至是系统详细说明改变时,JUnit 框架提供一个很好的方法来改善系统的坚固性.通过测试,您可以检

诊断Java代码: Impostor Type错误模式

当使用字段中特殊的标记来区别对象类型时,可能会产生标记对相关数据误贴标签的错误 ― 通称为 Impostor Type 错误模式.在诊断 Java 代码的这一部分中,Eric Allen 对这个错误的症状和起因进行了分析,详细说明了预防错误发生的方法,并讨论了一种吸引人的混合实现方法,这种方法不使用 impostor type,但最后,还是有很多相同的缺点产生.请在 讨论论坛与作者及其他读者分享您对本文的看法. 程序中除了最无关紧要的部分外都要对某些数据类型进行操作.静态类型系统提供了一种方法,

诊断Java代码:孤线程(Orphaned Thread)错误模式

在多线程代码中,使用驱动其它线程所负责的动作的单个主线程是常见的.这个主线程发送消息,通常是通过把它们放到一个队列中,然后其它线程处理这些消息.但是如果主线程抛出一个异常,那么剩余的线程会继续运行,等待更多输入到该队列,导致程序冻结.在诊断 Java 代码的这一部分中,专职 Java 开发者兼兼职捉虫者 Eric Allen 讨论检测.修复和避免这一错误模式. 用多线程编写代码对程序员大有好处.多线程能使编程(和程序)进行得快得多,而且代码能有效得多地使用资源.然而,跟生活中的很多事情一样,多线

java 登录 代码-Java代码设计登录的问题

问题描述 Java代码设计登录的问题 我在做毕业设计,现在遇到的问题是,我输入帐号和密码,然后选择学生,再点击登录,跳转到学生界面,我不知道为什么跳转不过去,求高手指点,不胜感激!![CSDN移动问答][1] 下面是我写的方法,新手,还望见谅 public void actionPerformed(ActionEvent e) { Connection dbConn = null; Statement stm = null; ResultSet rs = null; if(student.isS

诊断 Java 代码:设计轻松的代码维护

设计 本月,Eric Allen 解释了在使代码更易于维护的同时,避免和控制无理由的变化怎么会是保持代码健壮性的关键.他集中讨论了诸如函数样式代码编写之类的概念,以及标记字段.方法和类的方法来处理并防止可变性.Eric 还解释了本任务中单元测试和重构的角色,并提供了协助实现重构的两个工具.在相关论坛中与作者和其他读者分享您对本文的看法.(您也可以单击本文顶部或底部的"讨论",访问该论坛.)有效调试源自良好的编程.设计易于维护的程序是程序员面临的最困难挑战之一,其部分原因在于程序通常并不

诊断 Java 代码: 提高 Java 代码的性能 尾递归转换能加快应用程序的速度,但不是所有的 JVM 都会做这种转换

简介: 很多算法用尾递归方法表示会显得格外简明.编译器会自动把这种方法转换成循环,以提高程序的性能.但在 Java 语言规范中,并没有要求一定要作这种转换,因此,并不是所有的 Java 虚拟机(JVM)都会做这种转换.这就意味着在 Java 语言中采用尾递归方法将导致巨大的内存占用,而这并不是我们期望的结果.Eric Allen 在本文中阐述了动态编译将会保持语言的语义,而静态编译则通常不会.他说明了为什么这是一个重要问题,并提供了一段代码来帮助判断您的即时(JIT)编译器是否会在保持语言语义的