2020春软件构造lab4实验报告

2020年春季学期
计算机学院《软件构造》课程

Lab 4实验报告

目录

1 实验目标概述 1
2 实验环境配置 1
3 实验过程 1
3.1 Error and Exception Handling 2
3.1.1 处理输入文本中的三类错误 2
3.1.2 处理客户端操作时产生的异常 2
3.2 Assertion and Defensive Programming 2
3.2.1 checkRep()检查rep invariants 2
3.2.2 Assertion/异常机制来保障pre-/post-condition 2
3.2.3 你的代码的防御式策略概述 2
3.3 Logging 2
3.3.1 异常处理的日志功能 2
3.3.2 应用层操作的日志功能 2
3.3.3 日志查询功能 2
3.4 Testing for Robustness and Correctness 2
3.4.1 Testing strategy 2
3.4.2 测试用例设计 2
3.4.3 测试运行结果与EclEmma覆盖度报告 2
3.5 SpotBugs tool 2
3.6 Debugging 3
3.6.1 EventManager程序 3
3.6.2 LowestPrice程序 3
3.6.3 FlightClient/Flight/Plane程序 3
4 实验进度记录 3
5 实验过程中遇到的困难与解决途径 4
6 实验过程中收获的经验、教训、感想 4
6.1 实验过程中收获的经验和教训 4
6.2 针对以下方面的感受 4

1 实验目标概述
本次实验重点训练学生面向健壮性和正确性的编程技能,利用错误和异常处理、断言与防御式编程技术、日志/断点等调试技术、黑盒测试编程技术,使程序可在不同的健壮性/正确性需求下能恰当的处理各种例外与错误情况,在出错后可优雅的退出或继续执行,发现错误之后可有效的定位错误并做出修改。
实验针对Lab 3中写好的ADT代码和基于该ADT的三个应用的代码,使用以下技术进行改造,提高其健壮性和正确性:
 错误处理
 异常处理
 Assertion和防御式编程
 日志
 调试技术
 黑盒测试及代码覆盖度

2 实验环境配置
实验环境设置请参见Lab-0 实验指南。

除此之外,本次实验需要你在Eclipse IDE中安装配置SpotBugs(用于Java代码静态分析的工具)。请访问https://spotbugs.github.io,了解它并学习其安装、配置和使用。

在这里给出你的GitHub Lab4仓库的URL地址(Lab4-学号)。
https://github.com/ComputerScienceHIT/Lab4-1180300503.git
由于本次实验是Lab3的继续,请首先将你Lab3中master分支的最终代码复制一份,推送到Lab4的仓库里,然后其基础上完成本次实验任务。本次实验不能影响Lab3和Lab3仓库里的内容与commit历史。

3 实验过程
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 Error and Exception Handling
3.1.1 处理输入文本中的三类错误

  1. 输入文件中存在不符合语法规则的语句,例如某个元素定义的标签非法、元素定义的内容格式与语法规范不一致(例如最多1位小数但使用了2位小数、要求2位大写字母和2-4位数字但却使用了非大写字母或超过4位数字等)、元素定义中分量的数目或次序与规范不符合(例如航班号在日期前面出现,或缺少日期等)、等,在此不一一列举,只给出总的报告异常。

  2. 输入文件中存在标签完全一样的元素。例如存在多个航班计划项的“日期,航班号”信息完全一样。

  3.  输入文件中各元素之间的依赖关系不正确。例如:第一行出现的航班日期与内部出现的起飞时间中的日期不一致;降落时间中的日期与航班日期差距大于1天;同一个航班号,虽然日期不同,但其出发或到达机场、出发或到达时间有差异;在不同航班计划项中出现编号一样的飞机,但飞机的类型、座位数或机龄却不一致;等等。这里不一一列举。

3.1.2 处理客户端操作时产生的异常

  1. FlightScheduleApp

  2. TrainScheduleApp

  3. CourseCaleddarApp

3.2 Assertion and Defensive Programming
起飞和降落的机场不相同

航班的起飞时间必须要早于降落时间
采用判断语句的方式,提示用户输入错误,使用防御性编程
直至用户输入正确,程序才会进行下一步。

高铁的起至站和各途经车站不能重复,所分配的各个车厢不能有相同的编号

3.2.1 checkRep()检查rep invariants

3.2.2 Assertion/异常机制来保障pre-/post-condition

3.2.3 你的代码的防御式策略概述

  1. 在修改ADT的内容之后,需要确认修改后的ADT符合RI。此时,可以调用ADT私有方法checkRep()进行校验。在各个ADT中均有checkRep(),出现在构造器(immutable对象),也会出现在mutator(mutable对象)。
  2. 在API的操作会对ADT进行影响,若ADT为可变的,则要求Setter()参数正确。检查参数正确可以在API的方法中,也可以在ADT的方法中。
  3. 例如API在获得某计划项的资源时,会判断该ADT的资源是否为空;在API需要获得高铁的第i站的到达时间,在ADT的方法中会对i的取值进行断言(不能为0)。
    3.3 Logging

3.3.1 异常处理的日志功能
本实验中,日志功能的实现调用了 Java 的库 java.util.logging。

3.3.2 应用层操作的日志功能
声明一个日志管理类logKeeper,管理所有的日志信息,比如可以按照时间或者异常类型等等进行日志的查询。我们把App的日志信息输出到一个文件中,日志管理类logKeeper就可以读取文件信息创建多个日志类对象当客户端需要查询日志时,可以按照自己的格式来反馈给用户。
3.3.3 日志查询功能
功能为输入计划项的名称和日期
可以显示该计划项的所有信息,包括出发、到达时间,当前状态等。
3.4 Testing for Robustness and Correctness
3.4.1 Testing strategy
尽可能多的覆盖全部代码,采取逐一检验方法的方式进行
3.4.2 测试用例设计

3.4.3 测试运行结果与EclEmma覆盖度报告
语句覆盖度

分支覆盖度

路径覆盖度

3.5 SpotBugs tool
错误:

  1. 声明了许多无关变量,占用了大量资源
  2. 变量没有进行初始化,导致最后出现错误
  3. 方法的重构有问题

3.6 Debugging
3.6.1 EventManager程序
1.理解待调试程序的代码思想
经过循环找到对应时间的活动数量最大值,输出
2.发现并定位错误的过程
该代码所考虑的方面不全面,没有考虑不同的天数,只考虑了同一天的活动情况
3.你如何修正错误
新加了一个TreeMap,用来对应不同的天数
4.修复之后的测试结果

3.6.2 LowestPrice程序
理解待调试程序的代码思想
通过分治的思想,来不断递归求得最小代价
发现并定位错误的过程
发现数组越界等情况
你如何修正错误
重新定义了列表的size(),并在循环过程中注意不越界
修复之后的测试结果

3.6.3 FlightClient/Flight/Plane程序
理解待调试程序的代码思想
与lab3的思想基本类似
发现并定位错误的过程
String使用了==
Calendar类比较大小直接使用了<,>
你如何修正错误
String 比较要使用equals
Calendar类比较大小用before,after
修复之后的测试结果

4 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 时间段 计划任务 实际完成情况
2020-05-30 上午 读实验指导书,了解每一项任务 完成
2020-06-01 下午+晚上 对实验三的代码进行修改 完成
2020-06-04 一整天 对3.6的代码进行解读修改 完成
2020-06-05 上午 实验报告书写 完成
5 实验过程中遇到的困难与解决途径
遇到的难点 解决途径

日志不会用

询问同学,自己在网上查找资料

防御式编程不太理解含义

看老师的课件,自己了解

3.6的一些bug没有找出来

询问同学
6 实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训
对代码健壮性的理解更深了一步,在以后的编程中要时刻注意代码的健壮性,不然以后会改的很麻烦。
6.2 针对以下方面的感受
(1) 健壮性和正确性,二者对编程中程序员的思路有什么不同的影响?
要在正确性的前提下尽量提高健壮性,正确性是首先要保证的,其次健壮性也很重要,有时候二者发生冲突要正确权衡。
(2) 为了应对1%可能出现的错误或异常,需要增加很多行的代码,这是否划算?(考虑这个反例:民航飞机上为何不安装降落伞?)
我感觉要看这1%出现的异常重不重要,如果出现这个异常会导致毁灭性的打击,那么必须增加代码。否则,这样是不划算的。
(3) “让自己的程序能应对更多的异常情况”和“让客户端/程序的用户承担确保正确性的职责”,二者有什么差异?你在哪些编程场景下会考虑遵循前者、在哪些场景下考虑遵循后者?
前者编程的人要考虑诸多情况,可能工作量巨大,而后者用户需要更多的了解代码的功能,可能会加重用户的负担。我认为在99%情况下都应选择前者,作为代码开发人员,不能将希望寄托在用户的身上。
(4) 过分谨慎的“防御”(excessively defensive)真的有必要吗?你如何看待过分防御所带来的性能损耗?如何在二者之间取得平衡?
感觉没有必要,过分防御所带来的性能损耗巨大,所以要权衡。
(5) 通过调试发现并定位错误,你自己的编程经历中有总结出一些有效的方法吗?请分享之。Assertion和log技术是否会帮助你更有效的定位错误?
要考虑Java中自带的类的基本特征和使用,有可能使用不正确会带来严重的后果。
(6) 怎么才是“充分的测试”?代码覆盖度100%是否就意味着100%充分的测试?
应该测试的基本都测试了,就是充分的测试,代码覆盖度100%也不一定充分测试,要有注重点。
(7) Debug一个错误的程序,有乐趣吗?体验一下无注释、无文档的程序修改。
感觉是没有乐趣的,要不断思考这样做的缺陷。很头疼。
(8) 关于本实验的工作量、难度、deadline。
本次实验比较简单,难度不大,ddl还行。
(9) 到目前为止你对《软件构造》课程的评价和建议。
感觉学了一个学期的软件构造课程,对自己的影响不小,写代码考虑的事情变多了,而不是只要实现功能就行。
(10) 期末考试临近,你对占成绩60%的闭卷考试有什么预期?
希望可以线下考试,这样可以给我们更多的时间来消化所学的内容。还可以保证公平性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值