软件构造笔记--Lab4 Debugging, Exception Handling, and Defensive Programming


本次实验包括6小节,其中前5小节是对Lab3运用异常处理机制进行完善(包括防御式编程,logging,使用SpotBugs等),第6小节独立于Lab3,给3个有bug的程序,先理解思想然后debug。

Error and Exception Handling

可能出现的错误类别有:

  • 输入文件中存在不符合语法规则的语句
  • 输入文件中存在标签完全一样的元素
  • 输入文件中各元素之间的依赖关系不正确

本节实验中我考虑了以下8种不符合语法规则的情况:

  • 日期不符合语法规则
  • 航班名不符合语法规则
  • 机场名不符合语法规则
  • 时间不符合语法规则
  • 飞机编号不符合语法规则
  • 飞机型号不符合语法规则
  • 座位数不符合语法规则
  • 座位数不符合要求

先定义不符合语法规则的异常类,然后分别构造以上规则的正则表达式与输入文件进行匹配,若不能匹配则抛出异常,使用catch进行异常捕获,进行下一步处理。

对于第二类错误,使用HashSet存储所有日期+航班号的组合,判断输入文件是否有重复。

HashSet flightSet = new HashSet(); 

对于第三类错误,我考虑了以下四种情况:

  • 判断航班日期与时间是否一致
  • 判断同一个航班号的出发、到达机场是否一致
  • 判断同一编号的飞机的类型是否一致
  • 判断同一编号的飞机的座位数是否一致

是否满足依赖用HashMap保存键值并检验即可。

Assertion and Defensive Programming

在学习了前置条件和后置条件之后,编程时要注意在输入参数不满足前置条件时应该让程序Fail fast,也就是使用assert判断一个方法中的参数是否满足前置条件,另外ADT的RI也是防御式编程的重要手段。之前在实验3中考虑的RI并不全面,在Lab4中作了补充,例如对于Location类,新增了限制经纬度范围的RI:

      // RI:
	//  -180<=longitude<=180
	//  -90<=latitude<=90
	public void checkRep() {
		assert longitude<=180 && longitude>=-180;
		assert latitude <= 90 && latitude >= -90;
	}
	public Location(double longitude, double latitude, String 	name, boolean shareable) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.name = name;
		this.shareable = shareable;
		checkRep();
	}

等等,这里不一一列举。

Logging

本节主要训练Java的logger以及如何将日志输出到文件等功能,重复工作较多,最后要求实现日志的查询由于这个实验和信息检索实验撞了(太难了555)所以只实现了乞丐版,可以查询某一天的日志。

Testing for Robustness and Correctness

本节就是测试自己程序的健壮性如何,之前对Lab3的程序作了很多异常处理、防御性编程,接下来就要想办法构造尽可能多的错误输入,来测试程序能否正常退出,而不是出现其他意想不到的情况。

最后用EclEmma生成覆盖度报告。

SpotBugs tool

主要是学习使用SpotBugs这个插件的使用。一开始我用了之后Eclipse完全没反应,后来才知道要等一会并且在控制栏那里把SpotBugs的查看窗口打开才能看到bug:

Debugging

这里给了三个错误程序,要求debug。我是看了实验辅导的视频才理解原算法到底想要干嘛,这里debug的程序规模都比较小,多画画图总能做出来。这一节让我感受到了注释的重要性,我们以后写代码以后要写好注释,不然别人(甚至自己都)看起来非常费劲。

总结

一个学期的软件构造实验终于结束了。。。虽然不算学分绩导致实验上做的不是很完美,但是好歹也是个5分的大课,折磨我的同时也让我收获了很多。