第三单元总结
• (1)梳理JML语言的理论基础、应用工具链情况
JML语言理论基础
Java建模语言(Java Modeling Language,JML)是一种进行详细设计的符号语言,他鼓励你用一种全新的方式来看待Java的类和方法。JML是一种行为接口规格语言 (Behavior Interface Specification Language,BISL),基于Larch方法构建。BISL提供了对方法和类型的规格定义手段。所谓接口即一个方法或类型外部可见的内容。通过在Java代码中增加了一些符号,这些符号用来标识一个方法是干什么的,却并不关心它的实现。使用JML,我们就能够描述一个方法的预期的功能而不管他如何实现。通过这种方式,JML把过程性的思考延迟到方法设计中,从而扩展了面向对象设计的这个原则。
JML以javadoc注释的方式来表示规格,每行都以@起头。有两种注释方式,行注释和块注释。JML引入了大量用于描述行为的结构,比如有模型域、量词、断言可视范围、预处理、后处理、条件继承以及正常行为(与异常行为相对)规范等等。
JML应用工具链
JML相应的工具链,可以自动识别和分析处理JML 规格。常用的有openjml,其使用SMT Solver来对检查程序实现是否满足所设计的规格(specification)。目前openjml封装了四个主流的solver:z3, cvc4, simplify, yices2。z3由Microsoft开发的,并已在github上开源:https://github.com/Z3Prover/z3 其正式发布版可通过https://www.microsoft.com/en-us/download/details.aspx?id=52270获得。cvc4由Standford开发,可以通过http://cvc4.cs.stanford.edu/downloads/下载。
• (2)【改为选做,能较为完善地完成的将酌情加分】部署SMT Solver,至少选择3个主要方法来尝试进行验证,报告结果
• 有可能要补充JML规格
• (3)部署JMLUnitNG/JMLUnit,针对Graph接口的实现自动生成测试用例(简单方法即可,如果依然存在困难的话尽力而为即可,具体见更新通告帖), 并结合规格对生成的测试用例和数据进行简要分析
• (4)按照作业梳理自己的架构设计,并特别分析迭代中对架构的重构
1.第一次作业
第一次作业中,要求实现一个PathContainer类,该类可以对Path类对象进行存储和处理,这部分作业实际上没有涉及到算法的选择而且很简单,根据规格写出代码即可,我创建了一个Arraylist存储Path对象的ID,存储Path对象自身时,也使用了 Arraylist 存储,由于此次的作业有复杂度的要求,所以我选择了将查找的复杂度“分配”给了插入和删除的方式。
2.第二次作业
这次作业在第九次作业的基础之上进一步实现一个Graph类的图,并通过该图找到最短路径以及两个节点之间的连通性。我依旧使用了Arrraylist实现了图,并且通过每次插入删除时更新灵界矩阵的方法,运用弗洛伊德算法(时间复杂度是o(n^3)),玩完成了此次作业。
3.第三次作业
此次作业要在上一次作业的基础之上实现一个RailwaySystem类的图,有三个要求:
(1)查找最短路径:(2)不满意度最低:(3)花费最少。这次我的算法的选择是在年级群里大家给出的算法建议,但是我也一直无法整明这个算法的正确性,又找不到反例,虽说是通过了强测和互测,我还是有一点疑问,需要更进一步的学习。
• (5)按照作业分析代码实现的bug和修复情况
这三次作业中强测都通过了,但其实在完成作业的过程中,跟同学讨论也发现了bug,第三次作业在通过中测后发现一个初始化问题。
• (6)阐述对规格撰写和理解上的心得体会
在第一次作业中我机械地根据规格写出代码,觉得问题十分简单,只用考虑复杂度的问题即可,但在第二次和第三次作业中我发现(尤其是第三次作业),有时候看规格甚至不如指导书来得方便易懂,写着写着就错了。
而我的方法是:先看规格,翻译成自然语言,看不懂规格就去看指导书,但规格也有一个好处,会考虑到我自己考虑不到的特殊情况,这一点上我非常依赖于规格。
其实这足以见得我对规格的理解不够透彻与熟练,在学习的过程中我就在想,为了理解规格,是不是有自己来写规格会更好?
通过对jml的学习,我也体会到了好的架构设计对编程的重要性,自己编写jml也并不是一件容易的事情,是需要大量锻炼的,因此我也不能满足于目前的学习,眼光应当更长远,继续学习下去。