面向对象第三单元总结

一、JML语言理论基础

1.1 JML语言理论基础

JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言。JML是一种行为接口规格语言,基于Larch方法构建。BISL提供了对方法和类型的规格定义手段。所谓接口即一个方法或类型外部可见的内容。JML主要由Leavens教授在Larch上的工作,并融入了Betrand Meyer, John Guttag等人关于Design by Contract的研究成果。近年来,JML持续受到关注,为严格的程序设计提供了一套行之有效的方法。通过JML及其支持工具,不仅可以基于规格自动构造测试用例,并整合了SMT Solver等工具以静态方式来检查代码实现对规格的满足情况。

1.2 JML工具链

OpenJML:检查JML规格的正确性,主要调用SMT Solver进行检查。

下载方法:在eclipse的help栏中选择install New Software ,输入网址http://jmlspecs.sourceforge.net/openjml-updatesite进行OpenJML插件的下载。

JMLUuitNG:可根据规格自动化生成测试样例,进行单元测试。

官网链接:http://insttech.secretninjaformalmethods.org/software/jmlunitng/

jar 包链接:http://insttech.secretninjaformalmethods.org/software/jmlunitng/assets/jmlunitng.jar

二、部署JMLUnitNG,自动生成测试样例

JMLUnitNG的配置过程是参考讨论区的教程https://course.buaaoo.top/assignment/71/discussion/199  ,在Linux完成配置。

我的测试样例如下,写了一个简单的add函数:

package test;

public class Test {
    /*@ ensures \result == (num1 + num2);
      @ */
    public static int add(int num1, int num2) {
        return num1 + num2;
       }
       public static void main(String[] args) {
        add(123, 456);
    }
}

运行结果如下:

[TestNG] Running:
  Command line suite

Failed: racEnabled()
Passed: constructor Test()
Passed: static add(-2147483648, -2147483648)
Passed: static add(0, -2147483648)
Passed: static add(2147483648, -2147483648)
Passed: static add(-2147483648, 0)
Passed: static add(0, 0)
Passed: static add(2147483648, 0)
Passed: static add(-2147483648, 2147483648)
Passed: static add(0, 2147483648)
Passed: static add(2147483648, 2147483648)
Passed: static main(null)
Passed: static main({})

===============================================
Command line suite
Total tests run: 13, Failures: 1, Skips: 0

可以看出测试很不充分。对于int型的数据,只考虑了一些边界情况,0,-2147483648,2147483647。而对Object的子类,只用null进行测试。

三、 架构设计

(一)第一次规格作业

类图:

第一次作业比较简单,在MyPath类中,我定义了两种数据,private int[] nodes;和private final ArrayList<Integer> list,ArrayList<Integer> list,list数组仅在iterator中使。在MyPathContainer类中,定义了两个arraylist数组:private ArrayList<Path> plist 和 private ArrayList<Integer> pidList;通过这两个数组对路径经行管理。

(二)第二次规格作业

类图:

第二次作业中,MyPath类和第一次作业一样,而MyGraph 类则直接继承MyPathContainer,并自己实现几个方法。

实现getShortestPathLength()方法时,我采用Dijsktra算法,定义 HashSet spath保存已经经过的节点,定义HashSet s1表示目前时刻与fromNodeId拥有相同最短路径的节点。定义ArrayList<Integer> s2 表示下一时刻与fromNodeId拥有相同最短路径的节点。不断迭代下去,最后就能找到两个节点的最短距离。

(三)第三次规格作业

类图:

第三次作业中,MyPath大部分和第二次作业一样,只多了一个方法public int getUnpleasantValue,计算出两个相邻节点间的不满意度。MyRailwaySystem类直接继承MyGraph 类,并自己实现几个方法。另外,定义spend类,保存节点,节点来源节点,和节点开销,用于求最小开销和最小不满意度。

实现getLeastTransferCount()方法和实现第二次作业的getShortestPathLength()方法相似,也是利用Dijsktra算法,HashSet spath保存已经经过的节点,定义HashSet s1表示目前时刻与fromNodeId拥有相同换乘数节点。定义ArrayList<Integer> s2 表示下一时刻与fromNodeId拥有相同换乘数的节点。不断迭代下去,最后就能找到两个节点的最短换乘数。

实现getConnectedBlockCount()方法时,首先任选一个没有被选取的节点A,不断循环遍历所有Path,将与A相连的path都移除。然后再任选一个没有被选取的节点B,不断循环遍历所有Path,将与B相连的path都移除,依次类推就能找出相连块的个数;

实现getLeastUnpleasantValue方法和实现 getLeastTicketPrice方法相似,都是用Dijsktra算法。定义HashSet tpath 保存已经经过的节点,定义int node表示当前迭代节点,定义ArrayList<Spend> s1表示node可达节点。定义HashSet s2  表示node的来源路径。每次从S1中选取不满意度最少的节点继续往下迭代。不断迭代下去,最后就能找到两个节点的最小不满意度。

getLeastTicketPrice()方法的实现和getLeastUnpleasantValue()方法类似。

三、Bug与修复:

第一次作业:出错在MyPath类,在将path中的数据赋给arraylist时,将复制的循环写在了iterator里面,导致每次调用iterator,arraylist都会多复制一遍,打印输出path时就会多次输出同一个path,从而出错了。

第二次作业:出错在 MyGraph类,在方法getShortestPathLength和isConnected中,我先判断fromNodeId 和toNodeId是否相等,相等则直接输出0。但是我却没有意识到,当fromNodeId == toNodeId时,如果fromNodeId不在图中,则应该抛出异常,而不是输出距离为0;

第三次作业:使用动态Dijsktra算法,导致运行时间过长,出现了超时现象

四、对规格的心得体会:

因为自己也参与写过一些比较复杂规格比较大的程序,能深刻理解到规格的重要性。规格能让合作伙伴知道你写代码的功能,规格能让自己在很久之后也能明白自己写的程序的功能,规格还能让客户更好的理解自己写的程序的功能。特别是函数具体代码没开源的一些程序,有一个好的规格,才能让客户明白这个函数的作用。

在这次作业中,也让我深刻理解了仔细读规格的重要性,第一次和第二次作业的bug都是因为没有好好的读规格,写程序都按照自己想当然的想法,没有深挖规格体现的意思,才导致了bug的产生。

原文地址:https://www.cnblogs.com/CC1090348107/p/10905937.html

时间: 2024-10-31 04:40:25

面向对象第三单元总结的相关文章

面向对象第三单元博客(JML)

// demo/Graph.java package demo; ? import java.util.ArrayList; ? public class Demo { /*@ public normal_behaviour @ ensures \result == lhs - rhs; */ public static int compare(int i, int j) { return i - j; } ? public static void main(String[] args) { c

面向对象第三单元(JML)总结体会

一.JML语言 定义 Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约方法设计 和Larch 系列接口规范语言的基于模型的规范方法 . 理论基础 JML是契约式语言的一种具体表现形式. 契约(Contact):声明一个函数/方法的时候,对函数的输入和输出所具备的性质是有所期望和规定的.有时候这种性质会被我们明确的写出来,有时候会被我们忽略掉.这些期望和规定就是Contract. 而契约设计的核心便是断言(assertion) :永远为真

面向对象第三单元

JML理论基础及应用工具链 理论基础 JML,Java 建模语言,可以规范 java 类和接口的设计.JML是一种行为接口语言,也就是说,其规范了java代码的行为和语义接口.java 类和接口的语义规范包括其方法签名,名字和域的类型等.这通常指的是 API .java 类和接口的行为接口描述了编程者使用这个 API 的方式.就行为来说,JML 可以对方法的前置条件与后置条件细化,以及类的不变式等.这属于契约编程. 工具链 最基本的工具是 parsing 和 typechecking,这由 jm

第三单元JML规格总结

第三单元学习了JML规格描述语言,根据JML的规定编写对应的方法,同时也复习了数据结构的知识,并且也考察了程序的时间复杂度. 一.JML语言 理论基础 JML全名为Java Modeling Language(Java建模语言),在Java代码中增加一些不影响程序正常编译运行的符号用来标识一个方法是干什么的.通过使用JML,程序员能够描述一个方法的预期的功能而不管具体实现方式.JML把过程性的思考延迟到方法设计中,从而遵循了面向对象设计的一个原则即将过程性的思考尽可能地推迟.而且JML语言为了描

规格化设计——OO第三单元总结

规格化设计--OO第三单元总结 一.JML语言理论基础.应用工具链 1.1 JML语言 ? JML(java modeling language)是一种描述代码行为的语言,包括前置条件.副作用等等.JML是一种行为接口规格语言 (Behavior Interface Speci?cation Language,BISL),基于Larch方法构建. ? 通过使用JML,我们可以忽略一个类.一个方法内部的具体实现,专注于描述方法的预期功能,从而把过程性的思考延迟到方法设计中,扩展了面向对象设计的原则

面向对象的三个特征。

引用文章:http://blog.csdn.net/ma1kong/article/details/4457044 引用介绍:一篇偏向JAVA的文章.对此,我删除了一些文字,保持对C++适用. 面向对象的三个特性:封装,继承,多态. 特定的作用:封装可以隐藏实现细节,使得代码模块化:继承可以扩展已存在的代码模块(类):都属于代码重用.多态则是为了实现接口重用.多态是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用(个人理解:实际就是虚函数的作用). 一.封装 1:封

面向对象的三个特性:封装

面向对象的三个特性:封装.继承.多态 //1.封装目的:让类更加安全,不让外界直接访问类的成员 //具体做法[1]将成员设为私有:访问修饰符 class ren { [var $age;] private $age; } $r=new ren(); echo $r->age;//访问不到 [2]造成员方法来操作变量 class ren { private $age; //制造方法去给变量$age赋值 public function SetAge($a) { if($a>18 and $a<

01 面向对象的三条主线

面向对象的三条主线: 1.类及类的成分 2.面向对象的三大特性 3.其他的关键字:this super import package abstract static final interface等 1.java程序是关注于类的设计.类从代码的角度:并列关系!   从执行.设计的角度:关联关系.继承关系.聚合关系 class A{ } class B{ A  a = new A(); } 2.类的成分:属性   方法  构造器  代码块  内部类 2.1 属性:①变量的分类:成员变量(属性 Fi

荒芜的周六-PHP之面向对象(三)

hi 又是开森的周六了.积攒的两周的衣服,终于是差不多洗完了.大下午的才来学点东西~~ 1.PHP面向对象(三) 四.OOP的高级实践 4.3 Static-静态成员 <?phpdate_default_timezone_set("PRC");/** * 1. 类的定义以class关键字开始,后面跟着这个类的名称.类的名称命名通常每个单词的第一个字母大写. * 2. 定义类的属性 * 3. 定义类的方法 * 4. 实例化类的对象 * 5. 使用对象的属性和方法 */ class