诊断Java代码: Repl提供交互式评价

通常,在运行 Java 程序时,必须使用 String[] 输入参数将参数传入,从 main() 方法运行程序。但是如果程序仍在调试中,那么,这可能会成为一项繁重的任务。本月,Eric Allen 讨论对程序中的表达式和语句进行交互式评价的优点,并且提供几个帮助您处理这一任务的 Java repl(“read-eval-print-loop”工具,“读取-评价-打印-循环”工具)。他还讨论交互式评价如何帮助构建 GUI 和探索新的 API。

多数程序都包含很多方法,这些方法分布在为数众多的类中。毫无疑问,从程序的 main 入口点测试所有这些方法,即使不是不可能的,也是很困难的。

这就是单元测试之所以有用的原因。许多程序员和软件设计人员(包括我自己)强调单元测试在编写健壮的的软件时是有用的。但是如果您想能够以一种交互性更好的方式访问程序中的各种元素时,则可能要折衷一下。

当确实要这样做时,为每个结果编写、编译并运行新的单元测试就会很快变成一件繁重的事情。我发现,当不能预知给予特定输入后程序将表现出什么行为时(例如:在 AI 程序中可能就会出现这种情况),尤其如此。

那么,该怎么办呢?

不要为小改动着急

为了作一个类比,请考虑用通常情况下进行编译的语言(例如:Java 或 C++)编程和用在更多情况下进行解释的语言(Python 或 Scheme)编程之间的差异。

在编译型语言中,每个编写/测试/调试循环都必须包含编译这一额外的步骤,这可能是一个单调乏味的经历,尤其是对于一些小改动而言。这可能会使我们得出结论说,解释型语言更流畅,因而也更易于修改。(这种灵活性是有代价的:解释型语言通常更少对代码执行静态检查,例如类型检查。)

正如有时候我们可能想对程序作个改动,但不必经历重编译的麻烦一样,我们也可能想检查程序中的一些元素,但不必例行公事般在套件中添加一个新的单元测试。当确实想这样做时,拥有传统上称为“读取-评价-打印-循环”(即 repl)的工具可能会有所帮助。

repl是一个基于文本的工具,它以表达式作为输入,在特定程序的上下文中进行评端,然后显示结果。接着,它等待获得另一个表达式作为输入,然后重复这些操作。这样的工具源于类似 Lisp 的语言,但它们也能在更新的语言(例如:Python)中使用。

repl 在 Java 编程中的好处

这样的工具并非仅仅在这些语言中是有用的。Java 程序员也可以从使用 repl 中获得好处,不只是调试方面,在其它方面也可以。

构建 GUI

当组装一个 GUI 时,有许多组件需要布置和连接。当构造 GUI 时,您肯定会碰到以下这些事情:

组件之间将以不可见的方式相互作用。

在运行 GUI 之前写出其所有代码是相当费时的。

一旦您看到了 GUI 的实际视觉效果,不可避免地,您将会想更改 GUI 的某些方面。

这个问题的一种常见的“解决方案”是使用图形化的 GUI 构建工具,例如那些包含在 JBuilder、Forte 和其它 IDE 中的 GUI 构建工具。我个人不喜欢这种办法 ― 您很难知道这个工具会给您生成什么样的 Java 代码,您也不可能在修改所生成的代码时不冒丧失与 GUI 构建工具的兼容性的风险(事实上,有些 IDE 强行禁止您修改机器生成代码的任何部分)。

此外,许多这类 GUI 构建工具在生成 Java 代码时都使用专用 GUI 库,因而限制了 GUI 的兼容性。

我发现使用 repl 来构建 GUI 要容易得多。我完全可以交互地定义每一个 GUI 组件,然后依次显示它。我能够立刻修正任何不喜欢的东西。然后,我可以与之交互并将这些组件粘贴到程序中。

时间: 2016-02-12

诊断Java代码: Repl提供交互式评价的相关文章

诊断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代码: 设计可扩展应用程序,第3部分

对应于我们上一篇" 诊断 Java 代码"中所讨论的透明盒可扩展性,黑盒可扩展性是指,在源代码既不能查看也不能修改时,可以扩展软件系统的方法.通常通过系统配置或使用特定于应用程序的脚本语言来进行这样的扩展.在本专题中,Eric Allen 讨论了何时设计黑盒可 扩展性的系统是有意义的,并提供了如何有效地实现这一设计的一些想法.阅读了本文后,您将知道何时使用黑盒并掌握如何实现它的一些技巧. 我已在以前的文章中谈到了代码重用设计策略的重要性(主要是因为各种信息处理任务的差异和相应费用的增加

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

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

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

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

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

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

诊断Java代码: 在规范钢丝上行走

要构建可靠的软件,程序规范很关键.没有良好定义的规范,很难诊断软件系统的异常行为.但是很多软件系统的程序规范定义得很差劲.而且更糟的,是许多软件系统根本就没有规范. 直观的看,程序规范是对程序行为的一种描述.它可以采取许多形式,但无论采取何种形式,都有一条主线贯穿所有实例:必须有某种类型的系统规范,因为您得依靠它来判断系统是否运转正常. 规范可以形式化也可以松散地定义,这取决于开发中系统的稳定性和危险程度,还与开发完毕后修改系统的容易程度有关. 我们将通过讨论规范为什么重要.为什么会经常被忽略以

诊断Java代码: 将时态逻辑用于错误模式

尽管传统的断言可以增加对 Java 代码所作的检查次数,但仅用它们,还是有许多检查无法完成.处理这种情况的方法之一就是使用 时态逻辑.请回忆上个月的文章" Assertions and temporal logic in Java programming",时态逻辑有助于提供比程序中的方法更有力的断言,从而有助于增强用其它方式难以正式表达的不变量. 我们不必费力搜寻去发现有助于防止我们程序出错的许多有用的不变量.实际上,可以通过使用此类时态逻辑断言来加大我们消除一些最常见错误模式的力度