其他分享
首页 > 其他分享> > OO第三单元总结

OO第三单元总结

作者:互联网

一、JML概述

1.1 JML理论基础

JML简介

  JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言。JML是一种行为接口规格语言(Behavior Interface Specifification Language,BISL),基于Larch方法构建。   一般而言,JML有两种主要的用法:   (1)开展规格化设计。这样交给代码实现人员的将不是可能带有内在模糊性的自然语言描述,而是逻辑严格的规格。   (2)针对已有的代码实现,书写其对应的规格,从而提高代码的可维护性。这在遗留代码的维护方面具有特别重要的意义。

注释结构

  JML以javadoc注释的方式来表示规格,每行都以@起头。有两种注释方式,行注释和块注释。其中行注释的表示方式为 //@annotation ,块注释的方式为 /* @ annotation @*/ 。按照Javadoc习惯,JML注释一般放在被注释成分的紧邻上部。    纯粹查询方法(/*@ pure @ */),即方法的执行不会有任何副作用。   requires子句定义该方法的前置条件(precondition)。   副作用范围限定,assignable列出这个方法能够修改的类成员属性。   ensures子句定义了后置条件。   如果是在Interface中声明规格变量,则要求明确变量的类别。

JML表达式

原子表达式
量化表达式
集合表达式
集合构造表达式:可以在JML规格中构造一个局部的集合(容器),明确集合中可以包含的元素。集合构造表达式的一般形式为:new ST {T x|R(x)&&P(x)},其中的R(x)对应集合中x的范围,通常是来自于某个既有集合中的元素,如s.has(x),P(x)对应x取值的约束。
操作符

方法规格

方法规格的核心内容包括三个方面,前置条件、后置条件和副作用约定。其中前置条件是对方法输入参数的限制,如果不满足前置条件,方法执行结果不可预测,或者说不保证方法执行结果的正确性;后置条件是对方法执行结果的限制,如果执行结果满足后置条件,则表示方法执行正确,否则执行错误。副作用指方法在执行过程中对输入对象或 this 对象进行了修改(对其成员变量进行了赋值,或者调用其修改方法)。

类型规格

类型规格指针对Java程序中定义的数据类型所设计的限制规则,一般而言,就是指针对类或接口所设计的约束规则。从面向对象角度来看,类或接口包含数据成员和方法成员的声明及或实现。不失一般性,一个类型的成员要么是静态成员(static member),要么是实例成员(instance member)。一个类的静态方法不可以访问这个类的非静态成员变量(即实例变量)。静态成员可以直接通过类型来引用,而实例成员只能通过类型的实例化对象来引用。

1.2 JML应用工具链

二、部署工具链

  下载地址 :http://insttech.secretninjaformalmethods.org/software/jmlunitng/

  去除了Person类和Group类的接口,改成了新的Person类和Group类。

  需要补全代码中的HashMap<>括号里的内容。

  修改重名的内容

  命令行输入以下几条指令:

java -jar jmlunitng.jar test/Group.java

javac -cp jmlunitng.jar test/*.java

java -jar openjml.jar -rac test/Group.java test/Person.java

java -cp jmlunitng.jar test.Group_JML_Test
结果如下:

[TestNG] Running: Command line suite Passed: racEnabled() Passed: constructor Group(-2147483648) Passed: constructor Group(0) Passed: constructor Group(2147483647) Failed: <<test.Group@64cee07>>.addPerson(null) Failed: <<test.Group@1761e840>>.addPerson(null) Failed: <<test.Group@5ecddf8f>>.addPerson(null) Failed: <<test.Group@3f102e87>>.delPerson(null) Failed: <<test.Group@27abe2cd>>.delPerson(null) Failed: <<test.Group@5f5a92bb>>.delPerson(null) Passed: <<test.Group@6fdb1f78>>.equals(null) Passed: <<test.Group@51016012>>.equals(null) Passed: <<test.Group@29444d75>>.equals(null) Passed: <<test.Group@44e81672>>.equals(java.lang.Object@60215eee) Passed: <<test.Group@4ca8195f>>.equals(java.lang.Object@65e579dc) Passed: <<test.Group@61baa894>>.equals(java.lang.Object@b065c63) Passed: <<test.Group@768debd>>.getAgeMean() Passed: <<test.Group@490d6c15>>.getAgeMean() Passed: <<test.Group@449b2d27>>.getAgeMean() Passed: <<test.Group@5479e3f>>.getAgeVar() Passed: <<test.Group@27082746>>.getAgeVar() Passed: <<test.Group@66133adc>>.getAgeVar() Passed: <<test.Group@7bfcd12c>>.getConflictSum() Passed: <<test.Group@42f30e0a>>.getConflictSum() Passed: <<test.Group@24273305>>.getConflictSum() Passed: <<test.Group@5b1d2887>>.getId() Passed: <<test.Group@46f5f779>>.getId() Passed: <<test.Group@1c2c22f3>>.getId() Passed: <<test.Group@33e5ccce>>.getRelationSum() Passed: <<test.Group@5a42bbf4>>.getRelationSum() Passed: <<test.Group@270421f5>>.getRelationSum() Passed: <<test.Group@52d455b8>>.getValueSum() Passed: <<test.Group@4f4a7090>>.getValueSum() Passed: <<test.Group@18ef96>>.getValueSum() Passed: <<test.Group@6956de9>>.groupSize() Passed: <<test.Group@769c9116>>.groupSize() Passed: <<test.Group@6aceb1a5>>.groupSize() Failed: <<test.Group@2d6d8735>>.hasPerson(null) Failed: <<test.Group@ba4d54>>.hasPerson(null) Failed: <<test.Group@12bc6874>>.hasPerson(null) Passed: <<test.Group@de0a01f>>.updateRelation(-2147483648, -2147483648, -2147483648) Passed: <<test.Group@4c75cab9>>.updateRelation(-2147483648, -2147483648, -2147483648) Passed: <<test.Group@1ef7fe8e>>.updateRelation(-2147483648, -2147483648, -2147483648) Passed: <<test.Group@6f79caec>>.updateRelation(0, -2147483648, -2147483648) Passed: <<test.Group@67117f44>>.updateRelation(0, -2147483648, -2147483648) Passed: <<test.Group@5d3411d>>.updateRelation(0, -2147483648, -2147483648) Passed: <<test.Group@2471cca7>>.updateRelation(2147483647, -2147483648, -2147483648) Passed: <<test.Group@5fe5c6f>>.updateRelation(2147483647, -2147483648, -2147483648) Passed: <<test.Group@6979e8cb>>.updateRelation(2147483647, -2147483648, -2147483648) Passed: <<test.Group@763d9750>>.updateRelation(-2147483648, 0, -2147483648) Passed: <<test.Group@5c0369c4>>.updateRelation(-2147483648, 0, -2147483648) Passed: <<test.Group@2be94b0f>>.updateRelation(-2147483648, 0, -2147483648) Passed: <<test.Group@d70c109>>.updateRelation(0, 0, -2147483648) Passed: <<test.Group@17ed40e0>>.updateRelation(0, 0, -2147483648) Passed: <<test.Group@50675690>>.updateRelation(0, 0, -2147483648) Passed: <<test.Group@3ac42916>>.updateRelation(2147483647, 0, -2147483648) Passed: <<test.Group@47d384ee>>.updateRelation(2147483647, 0, -2147483648) Passed: <<test.Group@2d6a9952>>.updateRelation(2147483647, 0, -2147483648) Passed: <<test.Group@22a71081>>.updateRelation(-2147483648, 2147483647, -2147483648) Passed: <<test.Group@3930015a>>.updateRelation(-2147483648, 2147483647, -2147483648) Passed: <<test.Group@629f0666>>.updateRelation(-2147483648, 2147483647, -2147483648) Passed: <<test.Group@1bc6a36e>>.updateRelation(0, 2147483647, -2147483648) Passed: <<test.Group@1ff8b8f>>.updateRelation(0, 2147483647, -2147483648) Passed: <<test.Group@387c703b>>.updateRelation(0, 2147483647, -2147483648) Passed: <<test.Group@224aed64>>.updateRelation(2147483647, 2147483647, -2147483648) Passed: <<test.Group@c39f790>>.updateRelation(2147483647, 2147483647, -2147483648) Passed: <<test.Group@71e7a66b>>.updateRelation(2147483647, 2147483647, -2147483648) Passed: <<test.Group@2ac1fdc4>>.updateRelation(-2147483648, -2147483648, 0) Passed: <<test.Group@5f150435>>.updateRelation(-2147483648, -2147483648, 0) Passed: <<test.Group@1c53fd30>>.updateRelation(-2147483648, -2147483648, 0) Passed: <<test.Group@50cbc42f>>.updateRelation(0, -2147483648, 0) Passed: <<test.Group@75412c2f>>.updateRelation(0, -2147483648, 0) Passed: <<test.Group@282ba1e>>.updateRelation(0, -2147483648, 0) Passed: <<test.Group@13b6d03>>.updateRelation(2147483647, -2147483648, 0) Passed: <<test.Group@f5f2bb7>>.updateRelation(2147483647, -2147483648, 0) Passed: <<test.Group@73035e27>>.updateRelation(2147483647, -2147483648, 0) Passed: <<test.Group@64c64813>>.updateRelation(-2147483648, 0, 0) Passed: <<test.Group@3ecf72fd>>.updateRelation(-2147483648, 0, 0) Passed: <<test.Group@483bf400>>.updateRelation(-2147483648, 0, 0) Passed: <<test.Group@21a06946>>.updateRelation(0, 0, 0) Passed: <<test.Group@77f03bb1>>.updateRelation(0, 0, 0) Passed: <<test.Group@326de728>>.updateRelation(0, 0, 0) Passed: <<test.Group@25618e91>>.updateRelation(2147483647, 0, 0) Passed: <<test.Group@7a92922>>.updateRelation(2147483647, 0, 0) Passed: <<test.Group@71f2a7d5>>.updateRelation(2147483647, 0, 0) Passed: <<test.Group@2cfb4a64>>.updateRelation(-2147483648, 2147483647, 0) Passed: <<test.Group@5474c6c>>.updateRelation(-2147483648, 2147483647, 0) Passed: <<test.Group@4b6995df>>.updateRelation(-2147483648, 2147483647, 0) Passed: <<test.Group@2fc14f68>>.updateRelation(0, 2147483647, 0) Passed: <<test.Group@591f989e>>.updateRelation(0, 2147483647, 0) Passed: <<test.Group@66048bfd>>.updateRelation(0, 2147483647, 0) Passed: <<test.Group@61443d8f>>.updateRelation(2147483647, 2147483647, 0) Passed: <<test.Group@445b84c0>>.updateRelation(2147483647, 2147483647, 0) Passed: <<test.Group@61a52fbd>>.updateRelation(2147483647, 2147483647, 0) Passed: <<test.Group@233c0b17>>.updateRelation(-2147483648, -2147483648, 2147483647) Passed: <<test.Group@63d4e2ba>>.updateRelation(-2147483648, -2147483648, 2147483647) Passed: <<test.Group@7bb11784>>.updateRelation(-2147483648, -2147483648, 2147483647) Passed: <<test.Group@33a10788>>.updateRelation(0, -2147483648, 2147483647) Passed: <<test.Group@7006c658>>.updateRelation(0, -2147483648, 2147483647) Passed: <<test.Group@34033bd0>>.updateRelation(0, -2147483648, 2147483647) Passed: <<test.Group@47fd17e3>>.updateRelation(2147483647, -2147483648, 2147483647) Passed: <<test.Group@7cdbc5d3>>.updateRelation(2147483647, -2147483648, 2147483647) Passed: <<test.Group@3aa9e816>>.updateRelation(2147483647, -2147483648, 2147483647) Passed: <<test.Group@17d99928>>.updateRelation(-2147483648, 0, 2147483647) Passed: <<test.Group@3834d63f>>.updateRelation(-2147483648, 0, 2147483647) Passed: <<test.Group@1ae369b7>>.updateRelation(-2147483648, 0, 2147483647) Passed: <<test.Group@6fffcba5>>.updateRelation(0, 0, 2147483647) Passed: <<test.Group@34340fab>>.updateRelation(0, 0, 2147483647) Passed: <<test.Group@2aafb23c>>.updateRelation(0, 0, 2147483647) Passed: <<test.Group@2b80d80f>>.updateRelation(2147483647, 0, 2147483647) Passed: <<test.Group@3ab39c39>>.updateRelation(2147483647, 0, 2147483647) Passed: <<test.Group@2eee9593>>.updateRelation(2147483647, 0, 2147483647) Passed: <<test.Group@7907ec20>>.updateRelation(-2147483648, 2147483647, 2147483647) Passed: <<test.Group@546a03af>>.updateRelation(-2147483648, 2147483647, 2147483647) Passed: <<test.Group@721e0f4f>>.updateRelation(-2147483648, 2147483647, 2147483647) Passed: <<test.Group@28864e92>>.updateRelation(0, 2147483647, 2147483647) Passed: <<test.Group@6ea6d14e>>.updateRelation(0, 2147483647, 2147483647) Passed: <<test.Group@6ad5c04e>>.updateRelation(0, 2147483647, 2147483647) Passed: <<test.Group@6833ce2c>>.updateRelation(2147483647, 2147483647, 2147483647) Passed: <<test.Group@725bef66>>.updateRelation(2147483647, 2147483647, 2147483647) Passed: <<test.Group@2aaf7cc2>>.updateRelation(2147483647, 2147483647, 2147483647)

从测试数据可以看出,JMLUnitNG基本都是在测边界数据,如构造Group时用的是0、最大int、最小int,测试传入person的时候用null。

Fail的一些方法主要是因为调用的时候保证了不会传入NULL。

JMLUnitNG只注重对边界情况的测试,对一般情况则几乎没有涉及,没有随机性,测试意义不是很大。

三、作业架构设计

作业中需要注意存储方式,可能会给时间复杂度带来很大影响。最好多使用Hashmap,也可以与Arraylist结合使用,如Person类我用了一个动态数组存acquaintance,一个HashMap存acquaintance的id和value的对应。以及避免使用Arraylist.contains等可以避免的O(n)方法.

认真阅读JML规格避免看错条件。

3.1 第一次作业

第一次作业主要是熟悉JML,因此主要问题在认真阅读JML规格。

难点是isCircle方法的实现,我采用了bfs的方法实现。

用并查集会更好,不用每次都查找一遍。

UML类图

3.2 第二次作业

相比第一次作业加入了Group类和很多查询方法,如果每次都遍历查找时间复杂度势必会很高,而且测试指令条数很多,要注意缓存。

在加关系的时候也要注意更新缓存。

UML类图

3.3 第三次作业

第三次作业主要难点在三个函数,涉及了数据结构的图相关的知识。

    求权值最小路径,采用堆优化迪杰斯特拉算法,用Java的优先队列存储节点。

    判断两点是否点双联通,就是求是否存在两条通过两点且除这两点外没有相同点的路径,并且只有这两点直接连接的路径只能算一条。

    采用暴力遍历与这两点联通的所有点,每次去掉一个点bfs看两点是否还联通,如果存在使两点不联通的点则不是点双联通。

    注意两点直接连接的情况要单独考虑,去边后再bfs一次。

    采用并查集实现,求联通块的个数。

    同时把isCircle也改成了并查集实现。

UML类图

四、bug相关

三次作业均未测出bug。

互测中第二次作业有同学在加关系时没有更新缓存,有同学没有进行缓存导致遍历复杂度过高。

互测中第三次作业有同学方法实现上复杂度过高。

五、心得体会

规格撰写需要尽可能周到地考虑各种情况,注意JML格式。

阅读JML规格的时候要注意括号位置和符号的含义,看清楚数字,实现每一种情况。

这个单元接触了规格化设计,体会到了性能优化的重要性。但JML相关工具链还不太完善,有些表述也比较繁琐,使用还是需要进一步优化。

标签:OO,总结,2147483647,updateRelation,JML,表达式,Passed,2147483648,单元
来源: https://www.cnblogs.com/ldyblog/p/12941667.html