面向对象第三单元作业反思与总结

面向对象第三单元反思与总结

随着学期过半,面向对象课程也迎来了第三单元,之后再经过一个单元,面向对象课程就结束了。本单元但是主题是JML的相关知识。

一、JML的梳理与总结

1.JML语言简介

JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种行为接口规格语言,有两种主要的用法:

(1)开展规格化设计。

(2)针对已有的代码实现。

JML以javadoc注释的方式来表示规格,每行都以@起头。有两种注释方式,行注释和块注释。其中行注释的表示方式为//@annotation,块注释的方式为/* @ annotation @*/

2.JML表达式和规格

下面给出两个表格简要介绍JML语言一些常见的结构:

表达式 作用
\result 表示一个非void类型的方法执行所获得的结果,即方法执行后的返回值
\old(expr) 用来表示一个表达式expr在相应方法执行前的取值。
\not_assigned(x,y,...) 用来表示括号中的变量是否在方法执行过程中被赋值。
\forall 全称量词修饰的表达式,表示对于给定范围内的元素,每个元素都满足相应的约束。
\exists 存在量词修饰的表达式,表示对于给定范围内的元素,存在某个元素满足相应的约束。
\sum 返回给定范围内的表达式的和
\max\min 返回给定范围内的表达式的最大(小)值

此外还有诸如\not_modified(x,y,...) , \type(type) , \product这样的表达式,本次作业没有涉及,但都很实用。

规格 作用
requires 前置条件,要求调用者须满足此条件
ensures 后置条件,表示方法执行者确保方法执行返回结果满足此条件
assignable 表示可赋值
modifiable 表示可修改
pure 有些方法不会对对象的状态进行任何改变,也不需要提供输入参数,无需描述前置条件,也不会有任何副作用,且执行一定会正常结束。
public normal_behavior 一般指输入或方法关联this对象的状态在正常范围内时所指向的功能。
public exceptional_behavior 与正常功能相对应的异常功能,后面一般跟上signals子句表示抛出的异常

3.工具链

(1) openJML

用来检查JML的规格和语法。

(2) JMLUnitNG

可以通过JML规格,对各类自动生成测试用例进行测试。

(3) JUnit

对某一个类生成测试模板,可以在这里编写测试用例来对方法进行测试。

上述工具的前两种我在本地均配置失败。。bug越改越多,未能成功运行。所以我主要讲一下第三种Junit:

首先在IDEA中导入相关jar包:

面向对象第三单元作业反思与总结_第1张图片

之后建立测试文件夹,生成测试文件:

类名右键 --> Go To --> Test --> Create New Test

之后点击想要测试的方法:

面向对象第三单元作业反思与总结_第2张图片

测试文件中,使用@Test修饰的方法为测试方法。使用@Before修饰的方法为初始化方法,在开始进行测试之前执行。 使用@After修饰的方法为在进行测试之后执行的方法, 通常用于释放资源。

在每一个测试方法中,首先需要构造测试用例,然后使用断言判断其是否能够得到预期的结果,常用断言有:

assertEquals 是否相等
assertTrue 是否为真
assertFalse 是否为假
assertNotNull 是否不为null
assertNull 是否为null

下面是一部分示例:

面向对象第三单元作业反思与总结_第3张图片

这是针对isCircle()的单独测试,可以自由构造任何数据,缺点是较为繁琐,覆盖面不广,不如自动生成。

二、 架构设计与bug分析

这几次作业基本都是围绕已经给出的JML规格进行设计。

第九次作业:

几乎就是完全按照JML在写,唯一一个易错点在isCircle() ,自己和自己也认识,然后我采用的是BFS遍历的。

面向对象第三单元作业反思与总结_第4张图片

第十次作业:

增加了Group, 整体架构未发生太大变化,为了方便更新数据我将存放Person的容器改成HashMap。

面向对象第三单元作业反思与总结_第5张图片

第十一次作业:

增加了几个算法,这也是本次作业最难的地方,首先是最找最短路径的Dijkstra算法,然后是寻找点双连通分量的tarjan算法。但由于我之前从未使用过tarjan算法,最终我选择暴力查询,然后不出意外地超时了。。。

面向对象第三单元作业反思与总结_第6张图片

这几次作业出现的bug主要集中在算法上。在第九次作业时我只想着照搬JML的方法书写代码。第十次出现Group后我已经察觉到这似乎使用图来储存更合适,但最终未能实行。第十一次作业有了最短通路和点双连通分量,我才将整个数据结构大改,然后按照图的方法来写代码,但是由于图论部分较为生疏,写算法很费劲,也出了很多问题,导致强测结果不佳。

还有一个问题就是优化。我这几次作业写的第一版几乎都超时了,有些地方我优化完成,但有些到最后也没有调整好时间。究其原因,还是我的测试方法和工具用的不熟练,很多问题都只能手动debug,对于这几次作业来说非常麻烦,效果也不好。

三、 心得体会

JML作为一种规格语言,本质上是为了在写程序时提供一种设计方向,也便于交流和测试。但是写程序也不能完全照搬JML,最终的实现部分还是要自己完成,不管前期的算法,中期的优化,还是后期的测试,JML始终只是起到一个辅助作用,真正的代码还是该咋写咋写。这一单元我的成绩不够好,还是因为我本身算法部分偏薄弱,然后对于各种测试工具的使用不够熟练。就写代码这件事来说,只要基本功够扎实,不管在什么框架下完成都将会是很轻松的。

你可能感兴趣的:(面向对象第三单元作业反思与总结)