一、JML语言的理论基础和工具链
[The Java Modeling Language (JML) is a behavioral interface specification language that can be used to specify the behavior of Java modules. It combines the design by contract approach of Eiffel and the model-based specification approach of the Larch family of interface specification languages, with some elements of the refinement calculus.
Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为。它结合了Eiffel的契约方法设计和Larch系列接口规范语言的基于模型的规范方法,以及细化演算的一些元素。
The Java Modeling Language (JML) is a specification language for Java programs, using Hoare style pre- and postconditions and invariants, that follows the design by contract paradigm. Specifications are written as Java annotation comments to the source files, which hence can be compiled with any Java compiler.
Java Modeling Language(JML)是Java程序的规范语言,使用Hoare样式的前后条件和不变量,遵循契约范式的设计。规范作为Java注释注释写入源文件,因此可以使用任何Java编译器进行编译。
工具链:
- openJML:可以根据JML对代码进行静态的检查。
- JMLUnitNG:可以根据JML自动生成对应的测试样例。
二、部署JMLUnitNG
参考讨论区的方法,实现自动生成compare函数的测试用例,步骤如下:
可以看见自动生成的用例对compare函数的测试结果,进行了边界数据和0的测试。
三、架构设计
第九次作业:
第九次作业设计了Path和PathContainer类,其实一开始写的时候没想到之后会继承这么多次,不过还好设计的时候考虑了时间复杂度的问题。第一次作业问题也比较简单,选择合适的数据结构,在 O(1) O(n^2) 和 O(n) O(n) 中做个选择就好了。
不过由于compare方法的沙雕溢出错误导致强测WA得可怜,互测惨不忍睹。
第十次作业:
第十次作业新的Graph继承了PathContainer,已有的方法我基本没有改动,新增的方法如求最短路是通过简单的BFS实现的。
强测互测都一百昏!
第十一次作业:
其实就写一个层次图的最短路,性价比最好,好写也复杂度也低,整个作业不要两个小时。
求最短路还是 dijkstra 算法(堆优化),但是每一个点是一个 pair (pathid, nodeid)(pathid,nodeid)。这样的话三种最短路只有在更新 dis 的时候算法不同。
我们设当前用 (prePid, u)(prePid,u) 这个点(路径 pp 上面的点 uu) 来更新邻点,设邻点为 (nowPid, v)(nowPid,v)。那么我们就是用 dis[prePid][u] 加上边权,然后更新 dis[nowPid][v]。更新 dis 的函数如下。
private int updateDis(
int dis, int type, int prePid, int nowPid, int preV, int nowV
) {
int ret = dis;
if (type == 0) { // 求票价:边贡献1,换乘贡献2
ret += 1;
if (prePid != nowPid) {
ret += 2;
}
} else if (type == 1) { // 求不快乐度:边贡献max(preV, nowV),换乘贡献32
ret += Math.max(preV, nowV);
if (prePid != nowPid) {
ret += 32;
}
} else if (type == 2) { // 求最少换乘次数:边贡献0,换乘贡献
if (prePid != nowPid) {
ret += 1;
}
}
return ret;
}
但是由于命名的不走心和笔误,有个地方变量用错了,强测互测双双WA到爆炸,很惨,下次一定不取这么相似的变量名字了。
四、心得体会
JML的使用使得代码的逻辑变得更加清晰,在设计的时候对整体框架的把握更加准确,只需要仔细设计内部实现的性能就好了。撰写规格其实也是在理解了整个project的需求之后,高度提纯和分治各个需求,并且对于每一个方法和类都要有全面的考量,不是性能层面,而是实现需求还有保证安全层面的框架搭建。从两方面提升了自己设计和写代码的能力。只是希望自己不要再粗心错这错那了,我真的心在滴血……