《Java Bug模式》读书笔记

Bug模式是程序中已发生的bug和潜在bug之间重复出现的相互关系。有了这些模式和bug现象的知识,程序员就能很快识别新发生的bug,还可以预防这些bug的发生。

Bug模式与反模式有关,反模式是指被多次证明是失败的软件通用设计模式。这些设计的反面示例是传统正面设计模式的必要补充。虽然反模式也是一种设计模式,但Bug模式却是一种和编程错误相关的不正确的程序行为模式。这种关系与设计毫不相关,但是与编写代码和调试过程有关。

下面分别对13中Bug模式进行详细了解。

1.Rogue Tile模式

起因:通常是由在程序的不同部分之间复制和粘贴代码段产生的。

症状:您认为已经修正了导致错误行为的代码以后,程序还继续出现错误。

解决方法&预防措施:

面向方面的编程技术——通过在程序的类和函数中加入“方面(aspect)”来组织程序——有助于处理复制的代码(每个方面对应于程序的全局属性,例如,在方法中处理检查过的异常的方式)。

诊断清单:

在运行时,,尽管对所有事情都使用了相同的TreeVisitor接口,并在每个Visitor方法调用时插入的类型转换,但结果还是出现了ClassCastException异常。

2.Dangling Composite模式

起因:在使用递归定义的数据类型的代码报告一个空指针异常。

症状:在定义递归数据类型时,没有为一些基本类型定义其所属类。因此,空指针被插入到各种复合数据类型中去。然后客户端代码处理基本类型的方式不一致。

解决方法&预防措施:为保证一致性,确保基本类型已经过正确地表示和检查,为每个基本类型分配各自的类。

诊断清单:

3.Null Flag模式

起因:没有检查调用的方法是否将空指针作为返回值。

症状:使用空指针作为异常条件标志的代码段报告一个NullPointerException。

解决方法&预防措施:通过抛出异常报告异常条件。

诊断清单:

出现了一个NullPointerException异常,而且不知道它代表什么错误!出去Leaf类,并将Leaf节点用Branch中left和right字段的控制来表示是否可以修复ClassCastException异常,并减免类型转换的操作?

4.Double Descent模式

起因:部分代码在每次方法调用中向下访问了两层,并且在第二次时调度不当。

症状:程序在执行数据结构的递归下访问抛出ClassCassExceptions异常。

解决方法&预防措施:把执行强制类型转换的代码分解到每个类的单独方法中去。另一种方法是,检查不变量以确保强制类型转换成功执行。

诊断清单:

5.Liar View模式

起因:测试只是直接检查了模型的不同方面。

症状:GUI程序通过了测试集的测试,但是随后却表现出本该在那些测试中就已消除的行为。

解决方法&预防措施:在整体测试的基础上为模型和视图编写独立的测试程序。

诊断清单:

6.Saboteur Data模式

起因:一些内部数据被破坏,可能是语法上或者是语义上的破坏。

症状:用于存储和处理复杂的输入数据的程序在执行某项任务时意外地崩溃,而在执行其他类似任务时却安好无事。

解决方法&预防措施:对输入数据作尽可能多的完整性检查,而且越早越好。对于已经损坏的持久数据,研究这些数据并检查其完整性。

诊断清单:

将一行文本分为两个String是否会引起难以发现的、被毁坏的数据?

7.Broken Dispatch模式

起因:重载过程使得未经修改的方法激活了其他方法,而不是您所希望调用的方法。

症状:重载另一个方法之后,在测试从未修改过的代码时突然出现错误。

解决方法&预防措施:插入显式的向上类型强制转换;或者,重新考虑在不同类中提供的方法集。

诊断清单:

8.Impostor Type模式

起因:程序针对各种类型的数据使用带标记的字段,而不是独立的类。

症状:程序以相同的方式来处理不同类型的数据,或者数据与任何指定的类型都不匹配。

解决方法&预防措施:尽可能将概念上不同的数据类型分为几个独立的类。

诊断清单:

9.Split Cleaner模式

起因:程序的一些执行路径没有完成它们应该做的工作:程序未能在适当时刻一次性释放资源。

症状:程序未能正确地管理资源,而是泄露或过早地释放了这些资源。

解决方法&预防措施:把负责释放资源的代码移到获得资源的同一方法中。

诊断清单:

发现没有包括正确的释放代码的执行路径,是否应该向此路径添加释放资源的代码?

10.Fictitious Implementation模式

起因:接口中包括大量实现方案无法满足的不变量。

症状:当使用某个接口的特定实现方案时,处理此接口的客户端类发生中断。

解决方法&预防措施:修改接口实现方案,以包括这些不变量。如果这些不变量尚未写入接口文档,则在其中作明确说明。

诊断清单:

对于类型签名和单元测试,哪一种具备更强的表述性?

11.Orphaned Thread模式

起因:多个程序线程一直等待来自某个线程的输入,而该线程在抛出一个未被捕捉的异常后就退出程序了。

症状:多线程程序被锁定,可以或者无法将堆栈跟踪打印到标准错误。

解决方法&预防措施:把异常处理代码放到主线程中,告知依赖于该线程的其它线程已出现异常情况。另一种方法是,在退出的线程中放入处理程序,使它向其客户端传递相关信息。

诊断清单:

在什么类型的编程中,更有可能遇到被废弃的第2个线程?

12.Run-on Initializatier模式

起因:某个类的构造函数并未直接初始化所有的字段。

症状:在访问未被初始化的字段处抛出了一个NullPointerException异常。

是会眨眼的星星,而当火车弯曲而行,这些星群便上上下下的画着弧线,

《Java Bug模式》读书笔记

相关文章:

你感兴趣的文章:

标签云: