OOP第三次作业
第三单元博客作业
• (1)梳理JML
语言的理论基础、应用工具链情况
-
JML
语言理论基础Java建模语言(Java Modeling Language,
JML
)是一种进行详细设计的符号语言,他鼓励你用一种全新的方式来看待Java的类和方法。JML
是一种行为接口规格语言 (Behavior Interface Specification Language,BISL
),基于Larch方法构建。BISL
提供了对方法和类型的规格定义手段。所谓接口即一个方法或类型外部可见的内容。通过在Java代码中增加了一些符号,这些符号用来标识一个方法是干什么的,却并不关心它的实现。使用JML
,我们就能够描述一个方法的预期的功能而不管他如何实现。通过这种方式,JML
把过程性的思考延迟到方法设计中,从而扩展了面向对象设计的这个原则。
-
JML
应用工具链-
常见的有
openjml
,以及SMT Solver
来进行规格的静态检查 -
openJML
的-check
参数可以对规格进行检查(不对程序内容进行检查,单纯检查规格正确性) -
openjml
的-esc
参数可以对规格进行检查,同时指定SMT sovler
对程序的具体实现进行静态检查 -
openjml
的-rac
参数可以生成断言对程序进行运行时检查
-
• (2)【改为选做,能较为完善地完成的将酌情加分】部署SMT Solver
,至少选择3个主要方法来尝试进行验证,报告结果
• 有可能要补充JML
规格
• (3)部署JMLUnitNG
/JMLUnit
,针对Graph接口的实现自动生成测试用例(简单方法即可,如果依然存在困难的话尽力而为即可,具体见更新通告帖), 并结合规格对生成的测试用例和数据进行简要分析
JMLUnitNG
-
对于实现两个数相加的方法进行测试
-
使用jmlunitng.jar生成测试文件
-
JMLUnit
在三次作业中,我都使用了JMLUnit
来对我的方法进行断言检查,由于是单元测试,非常容易定位错误,是非常好用的,也检查出了几个bug,并且在进行我的代码重构时,也能使用它检测我的代码是否能支持之前的功能(雾)
下面是部分代码截图
• (4)按照作业梳理自己的架构设计,并特别分析迭代中对架构的重构
第一次作业类图如下:
第二次作业的类图如下:
第三次作业类图如下
从类图来看,显然我的类是很臃肿的,类之间的职责并不均衡,GrapgCal
的方法数量明显过多。在这次作业中,虽然CPU时间明显延长,并且允许的最多不相同点数也减少了,但还是害怕爆零(结果跑出来最长的也只有4s
左右,匿名感谢wjy
),而且有之前的Junit
的支持,将第二次的代码原封不动的copy过来,并对数据结构进行优化,也就造成了类的职责不均衡以及高耦合的情况的发生,这次是自己的着重点放错了(分奴),以后还是要好好遵守开闭原则,不对源代码进行修改,以免产生bug
这次我采用的方法是wjy
的floyd
算法,我将每条路径每个点之间的最短距离存在一个二维堆数组中,堆中的对象是我构建的Edge,存放长度以及其所在的路径ID,并重写了比较器,每次变更图结构时,维护这一二维数组中的堆,取一条路径上两点间的最短路径时,只需要取对应的堆顶元素即可,剩下就根据不同要求生成对应的初始数组,使用floyd
算法进行计算
• (5)按照作业分析代码实现的bug和修复情况
-
在公测以及互测中没有出现bug
• (6)阐述对规格撰写和理解上的心得体会
-
规格撰写的心得体会
规格的撰写是一个非常重要的步骤,一定一定要与实现隔离,不能束缚代码的具体实现,撰写者需要关心的是代码的数据形式以及其变化,用
JML
语法表现出这些变化,并且需要注意前置条件以及后置条件的完整性,要涵盖这一方法的所有信息。在继承一个父类后,还需要注意子类的规格要满足父类的规格,子类重写父类的方法时前置条件要放宽,后置条件要收紧,保证父类和子类规格的一致性
-
规格理解的心得体会
最大的体会的就是理解规格时要注重这一方法所要实现的目的,要达到怎样的效果,想清楚所有的规格之后,再去考虑代码的实现,并且最好考虑在此基础上的扩展性,构建一个较好的、易于扩展的框架