软件构造-lab4
实验目标概述
本次实验重点训练学生面向健壮性和正确性的编程技能,利用错误和异常处理、断言与防御式编程技术、日志/断点等调试技术、黑盒测试编程技术,使程序可在不同的健壮性/正确性需求下能恰当的处理各种例外与错误情况,在出错后可优雅的退出或继续执行,发现错误之后可有效的定位错误并做出修改。
实验针对 Lab 3 中写好的 ADT 代码和基于该 ADT 的三个应用的代码,使用以下技术进行改造,提高其健壮性和正确性:
⚫ 错误处理
⚫ 异常处理
⚫ Assertion 和防御式编程
⚫ 日志
⚫ 调试技术
⚫ 黑盒测试及代码覆盖度
实验过程
3.1 Error and Exception Handling
-
FileChooseException
对于这个自定义的 Exception 类主要用于处理所有需要重新输入文件的异常情况
-
FileGrammerException
e.g.
if(trackNum <= 0) {
bfReader.close();
throw new FileGrammerException("轨道数错误:" + trackNum, 23);
}
***********************************
catch (FileGrammerException e) {
// TODO: handle exception
throw new FileChooseException("请重新选择文件:" + e.getMessage());
}
等等还有一系列的设计的错误处理类型,不在此处赘述了。
3.2 Assertion and Defensive Programming
3.2.1 checkRep()检查invariants
所有的父类的checkRep()是所有子类的checkRep()的交集。
利用 checkRep 检查表示不变量,是一种比较常用的手段。在 debug 的阶段,将 checkRep 作为一种保障正确性的方式。
此处以子类 StellarSystemObject的checkRep为例,对于更加细节的checkRep在具体的包装调用处实现。
else if (rotationSpeed < -1 || rotationDiretion == null || ((angle >= 0) && (angle <= 360))) {
throw new FileChooseException("行星旋转状态不合法");
}
3.2.2 Assertion保障pre-/post-condition
在第三章的时候我们讲过防御式拷贝的内容,对于可变的数据类型,所有需要返回或者作为参数传入需要使用的地方均使用了防御式拷贝的方法,防止调用者可以利用reference 将内部的值做改变。
3.3 Logging
我是选择 Log4j 作为主要的日志记录工具,使用之前导入好log4j.jar包和创建好配置文件即可,这个在网上有很多详细的教程。
3.4 Testing for Robustness and Correctness
测试分两部分,一部分是测试正确性,一部分是测试健壮性。
3.5 SpotBugs tool
具体就是下载插件,找到bug的地方,按照提示修改即可。
放个例子:
空检查bug
3.6 Debugging
总的说来,老师提供给我们的这三个包含bug的代码,逻辑都很清晰,也不算很难改。代码里出现的主要问题。
Findmediansortedarrays 是寻找最中间的数字,并且判断是奇数个还是偶数个。
Topvotedcandidate是查找出在一个时间点上获得投票最多的人或者是在相同票数的情况下,最近获得票的那个人。
等等。
发现并定位错误的过程
设置断点,一步步测试,发现不合法输出或者输入,不断修改参数,直至程序的逻辑正确。
为每一个待调试的程序写测试。
用spotBugs也可以调试错误。