代码改变世界

OO第三单元JML规格系列作业总结

2019-05-22 11:05  爱啃黎的超人  阅读(243)  评论(0编辑  收藏  举报

 

JML理论基础

JML基础概念

JML是一种进行详细设计的符号语言。它为说明性的描述行为引入了许多构造。这些构造包括模型字段、量词、断言的可见度范围、前提条件、后置条件、不变量、合同继承以及正常行为与异常行为的规范。

用处

JML里的这些构造使得 JML 的功能变得非常强大,它在程序中的存在更为精确地描述这些代码是做什么的,并且JML能够高效地发现和修正程序中的bug,在应用程序升级时降低引入bug的机会,而提高代码的可维护性,提早发现客户代码对类的错误使用。

JML相关语法

注释结构

每行都以@起头

行注释://@annotation

块注释:/* @ annotation

...

@*/

表达式

原子表达式

\result表达式:

表示一个非 void 类型的方法执行所获得的结果,即方法执行后的返回值。

例如:

使用\result来表示 equals 的执行结果

量化表达式

 

 

方法规格

前置条件(pre-condition)

 

后置条件(post-condition)

 

(使用了逻辑或操作符表示约束场景)

应用工具链

1.Junit

JunitJava的单元测试的工具,负责单独测试JML语言描述出来的方法的正确性。

2.OpenJML

OpenJML根据配置的solver文件检查JML描述语言的语法正确性、程序代码的实现是否满足JML语言所描述的设计的规格,并且可以提示方法中存在的可能影响程序运行的问题。

JMLUnitNG使用实例

写了一个两个整型相乘(a*b)得到一个整型的测试程序Test.java。代码及Openjml运行结果如下:

 

 

架构设计分析

次作业

按照所给规格对函数进行重写

第一次接触规格,没有考虑到时间复杂度的问题,直接用的ArrayList

BUG分析

在考虑时间复杂度更换容器hashmap时粗心写错了一个if

类图

 

第二次作业

在第一次作业的基础上计算最短路径

使用Floyd算法进行计算

BUG分析

强测与互测均未出现BUG

类图

 

 

 

第三次作业

作业描述

在第二次作业的基础上,构建一个RailwaySystem,并且实现计算两站点之间的最少换乘,最低票价,最少不满意度。

由于计算最小值,需要根据新添的路径不停地更新路径的权重,这给我们的实现带来了极大的困难。

BUG分析

强测未出现BUG

 

这次作业大概有三种做法

1. 拆点

2. 动态权重

3. 使用离散知识解决

这里简单描述一下第三种

 

 

这里假设了两条路径 12342356

如图:

 

 

类图

 

 

代码Bug问题

第一次作业由于考虑时间的问题,在把ArrayList改成hashmap的过程中判断if语句出现了一些小问题,

导致了第一次作业强测分数不高

第二次作业无Bug但是从第二次作业当中加深了我对hashmap treemap的理解,第三次作业在计算连通块时出现了一个小错误~

对规格撰写和理解上的心得体会

规范的描述了进入函数的必要条件,对代码段做出的要求清晰明了,相比于用语言描述,JML大大降低了bug的出现概率,

以及理解上的问题。在实验课上根据所给代码自己撰写JML规格,在此过程中,我发现要对所描述的这段代码十分理解,

并且归纳总结出来他的思路,熟练使用规格语法,才能很好地描述这段代码的规格。

不过对于时间复杂度这一点,在第一次作业的版本一的时候并没有考虑到,几番斟酌之后把ArrayList换成了hashmap

对于直接从一个id找到此条路径,hashmapkey这一概率相对于ArrayList使用for循环变量找要快得多。