OO第三次博客作业
-
JML理论基础
JML是用于对Java进行规格化设计的一种表示语言。JML一方面可以在测试时为开发人员提供逻辑严格规格以避免二义性,另一方面可以提高代码的可维护性。
JML包含了类型规格、数据规格、方法规格等形式。其中,方法规格包括了前置条件、后置条件、副作用范围限定等约束。
-
JML工具链
Openjml
:以SML Solver为组建,进行jml语法检查、代码静态检查、生成运行时测试类JMLUnitNG/JMLUnit
: 针对类自动生成测试样例并进行测试。 -
部署JMLUnitNG并自动生成测试用例
通过JMLUnitNG
对Group
类自动生成的测试用例并进行的测试如图,可以看出,JMLUnitNG
主要对边界数据进行了测试。其中,addPerson
和delPerson
方法由于在规格中没有规定当person == null
时的情况而出现bug;updateRelation
方法当value
过大时,出现了溢出情况。
-
架构设计分析
三次作业的架构主要以课程提供的规格为约束。
第一次作业:对
Person
的存储使用了<PersonId, Person>
的Map
结构。第二次作业:新增
Group
类,为了降低程序复杂度,对Group
中的一些计算结果进行储存。第三次作业:
NetWork
中新增大量方法,为了降低isCircle
方法和queryBlockSum
方法的复杂度,person
之间的关系采用并查集结构来实现;queryMinPath
方法采用迪杰斯特拉算法来实现;queryStrongLinked
采用两层dfs方法来实现 -
bug分析
第一次作业:较简单,未出现bug。
第二次作业:
addToGroup
方法中对Group
人数进行了限制,而在代码实现时没有考虑到这一点。第三次作业:
queryMinPath
方法的时间复杂度过高,以至于CTLE
;queryStrongLinked
方法采用两层dfs
方法在数据量过大时发生了爆栈。 -
心得体会
- 在撰写规格时,应尽可能将前置和后置条件以及可能出现的异常都写清楚,不要留下逻辑上的漏洞;同时对代码实现的方式不要做过多的限制,比如add方法可能会存在的默认插入顺序问题。
- 在通过规格实现代码时,一定要满足规格中的所有条件;在此基础上,不要被规格中的数据结构所限制,尝试使用效率更高的实现方法。