OO第三单元作业总结
一、JML语言理论基础以及应用工具链情况梳理
JML是一种为Java量身定做的形式化的行为接口规范语言(BISL),用来规范Java程序模块(如类和接口)的行为及详细设计决策。它沿袭了BISL良好定义的形式语义,同时也继承了DBC语言较强的执行能力。一言以蔽之,JML就是再JAVA程序设计之前对其预先进行约束约定的语言。它在严格要求正确性的航空航天领域有着广泛的应用。
一般而言,JML有两种主要的用法:
(1)开展规格化设计。这样交给代码实现人员的将不是可能带有内在模糊性的自然语言描述,而是逻辑严格的规格。
(2)针对已有的代码实现,书写其对应的规格,从而提高代码的可维护性。这在遗留代码的维护方面具有特别重要的意义。
主要的应用工具有:OpenJML,JUnit,JUnitNG等。OpenJML可以检查JML的语法以及基本逻辑,JUnit以及JUnitNG主要是对JML规格进行测试,处理一些边界情况。
二、JMLUnit
代码如下
指令如下:
结果如下:
可以看出主要是对边界数据进行测试
三、作业分析
第九次作业
类图
第九次作业是规格化作业的第一次作业,代码实现简单清晰,基本上没有相关数据结构的优化和考虑,只需要简单使用一个哈希映射表来简化搜索过程即可,dsitincnode也同样可以用一个hashmap实现,内存储着节点出现的数量,方便在增删路径的时候进行维护。在此不做更多分析。
第十次作业
类图
第十次作业在第九次作业的基础上增加了四个函数,其中需要思考结构的优化的只有一个查找最短路径的方法。应为评测限制,该函数的实现不能够暴力地在每一次查找时进行一次搜索,所以应该存储下上一次求解出的最短距离,需要的时候可以直接访问容器得到路径,减少不必要的搜索。具体的做法是在add和remove指令时对存储最短距离的容器进行维护和更新,使用bfs算法求解。我是用的容器是hashmap,通过两层hashmap的嵌套已达到定位两个节点的目的,并存储下路径的距离。其他的函数例如节点是否联通可以直接通过最短距离矩阵得到答案。函数“容器是否存在点/边”可以通过distincnode的map和一个新建立的edge表得到。
第十一次作业
第十一次作业还是在之前作业的基础上进行功能的扩展,增加四个指令,连通块数量,最小换乘,最小票价,最低不满意度。对联通块的求解可以通过一次次删除相邻结点得到。而最短距离、最低不满意度、最小换乘、最小票价这四个问题可以通过抽象转化为同一个问题,即不同权值的图的最小距离求解。最小距离的求解可以通过floyd算法解决,所以本次作业的难点主要在于对于不同权值的图的生成。图的基本构成可以是如下形式:在同一条路径上的的结点为可直达的结点,在图上只用一条边连接并且附上对应的距离/票价/满意度权值,没换过一条边即换乘一次,相应的在权值上加上换乘的代价,图可以归一化处理。需要注意的是一条路径中可能会有重复节点或者环路,所以在处理之前需要对单条路径进行一次预处理,先得到路径内最小距离,才能在外部构时得到正确的图。
四、bug及修复状况
第九次第十次作业由于代码结构较为简单,在互测与强测中均为发现bug;第十一次作业由于未考虑路径内环路的问题,debug过程中选择在path内部处理并且返回,但违反了接口定义难以得到返回值,错漏百出。而后选择了在path外部生成图然后小图合并得到大图的方法完成,绕过了接口定义。
五、心得体会
在进行这个单元的作业之前,我从未听说过了解过关于规格化的知识。规格化的语言相比于自然语言,更加的严谨,无二义性,能够确保需求准确的从要求者传递到设计者,因此它的作用主要可以体现在要求者和设计者之间的协作上。同时我们还可以通过一些工具利用规格进行代码的测试,保证其完整实现了功能。它可以让程序员在不了解完整代码架构的情况下完成任务,节约了大量的时间,提高效率。