OO第三单元总结

一、关于JML

JML理论基础

所谓的JML,它是一种形式化的,面向JAVA的行为接口规格语言。对于我们所写的代码,正确性的重要性不言而喻,JML正是我们为了获得回答方法正确性问题的一种重要的技术手段,同时可作为我们开展测试设计时的依据,是多人协同开发时的交互基础。

方法规格:

OO第三单元总结_第1张图片

举一个例子,首先我们看到最上面的就是描述方法规格的类别。方法规格分为正常行为规格和异常行为规格,第一个规格写的normal_behavior对应的则是正常行为规格。Requires关键字描述的是规格的前置条件,assignable描述的是副作用范围,ensures描述的则是后置条件,中间的also关键词用于连接多个规格。下面第二个规格写的exceptional_behavior对应的是异常行为规格,通过signals子句抛出异常。最下面的是标题,用于定义过程的形式。

类型规格:

类规格组成包括对数据状态的要求,对方法的要求。类规格完整准确定义了一个类的设计目标和能力。对数据状态的要求包括不变式invariant和状态变化约束constraint。不变式是要求在所有可见状态下都必须满足的特性,而状态变化约束对对象状态的变化进行约束。

JML工具链

主要的JML工具有OpenJML,JMLUnitNG。可以对JML语法进行检查以及作为自动化单元测试的一个生成工具。

二、部署SMT Solver

OpenJML与Solver

Parsing and Type-checking

主要是检查JML规格的语法

我主要检查的是自己魔改的Person类,

OO第三单元总结_第2张图片

 OO第三单元总结_第3张图片

 OO第三单元总结_第4张图片

 OO第三单元总结_第5张图片

 

可以看到无任何返回信息,应该是没有问题吧。

Extended Static Checking

主要是利用Solver对按照JML编写的程序进行简单的静态检查。

OO第三单元总结_第6张图片

可以看到,我魔改的Person类是没有对queryValue写规格的,就是因为在静态检查的时候会返回神奇的错误,大概是报空指针之类的意思,我觉得可能是OpenJML有问题,所以把queryValue的规格删掉了,进行静态检查,就没有错误返回了,只剩下了13个警告。大概都是Solver无法对程序进行充分的解析导致的。

Runtime Assertion Checking

本功能是对JML编写的程序进行简单的运行时检查

可以看到对我的Person类没有抛出异常,并且在我的目录下生成了一个Person.class的文件。

OO第三单元总结_第7张图片

 

 OO第三单元总结_第8张图片

内容有接近5000行之多,前几十行内容大概如上,可以看到都是对代码运行过程的简单检查。

JMLUnitNG测试

OO第三单元总结_第9张图片

首先通过命令,我们得到测试类。并直接运行Group_JML_Test.java文件得到以下结果:

OO第三单元总结_第10张图片

可以看到所有的方法均没有问题。

架构设计

第一次作业

 OO第三单元总结_第11张图片

第一次作业都是按照规格来写的,只是单纯的对JML规格进行了翻译。

第二次作业

 OO第三单元总结_第12张图片

第二次作业同样是对规格的翻译,因此造成了非常严重的错误。

第三次作业

 OO第三单元总结_第13张图片

这是de完bug之后的,引入了图这一新对象,从而能在实现的过程中专注算法的编写。在之前是所有东西都混在MyNetwork里的。并查集,树状数组,迪杰斯特拉,DFS等混在里面显得很凌乱和臃肿。

BUG与修复情况

这一单元由于自己的疏忽,所以三次作业都爆炸了。第一次作业中判断是否存在某一始末端确定的链时没有考虑自环。第二次作业,因为没有考虑要修改第一次作业中写的addrelation,导致Group中的关系错误。第三次作业的错误在于,区间查询没有考虑区间不存在的情况,最短路没有描述边导致的TLE,以及判断双连通分量的时候一些小细节的错误。都已经得到修复。

心得体会

规格这一单元给人的初印象是简单,逻辑别人都给你写好了,你只要实现就可以了。但是实践下来发现并不是那么容易。首先第一点,在增加新功能的时候依然需要对老功能进行测试,虽然原来的方法规格没有变,但是为了满足新规格的正确性,老方法可能需要修改。其次,有很明显的可以抽象出来的对象时,还是要抽象出来,不用搁那硬做翻译。最后就是一定要进行大量的测试和时间复杂度的测试,不然很容易出错。

你可能感兴趣的:(OO第三单元总结)