OO第三单元自白

一、梳理JML语言的理论基础、应用工具链情况

JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言。

jml原子表达式:

  • \result:表示方法的返回值
  • \old(expr):表示expr在执行方法前的值
  • \not_assigned(x,y,...):表示括号中的变量是否在方法中被赋值
  • \not_modified(x,y,...):表示方法执行期间未发生变化
  • \nonnullelements(container):表示container中不会存储null
  • \type(type):返回type(为一个类型)对应的类
  • \typeof(expr):返回expr(为一个表达式)准确类型

jml量化表达式:

  • \forall: 给定范围全部元素
  • \exists:给定范围存在元素
  • \sum:给定范围表达式的和
  • \product:给定范围表达式的积
  • \max:给定范围内的最大值
  • \min:给定范围内最小值
  • \num_of:给定范围满足条件的个数

jml方法规格:

  • 前置条件:requires
  • 后置条件:ensures
  • 副作用范围限定:assignable 、modifiable
  • signals(Exception e) b_expr:当b_expr为真时,抛出e异常

jml类型规格:

  • 不变式invariant
  • 状态变化约束constraint

jml的工具链:

截图来自网络:http://www.eecs.ucf.edu/~leavens/JML/documentation.shtml?tdsourcetag=s_pcqq_aiomsg

二、使用JMLUnit实现生成测试用例:

 1 public class Test {
 2 
 3     public static void main(String[] args) {
 4         int a = 2;
 5         int b = 4;
 6         com(a, b);
 7     }
 8 
 9     //@ ensures \result == (a + b) ;
10     public static int com(int a, int b) {
11         return a-b;
12     }
13 
14 }

在这种情况下,程序进行了报错。

 

但是其实一开始,我写的程序稍微复杂了一点,其并未进行报错。。。

具体程序如下,经过测试,竟然神奇的通过了测试。真是神奇。

 1 public class Test {
 2 
 3     public static void main(String[] args) {
 4         int a = 2;
 5         int b = 4;
 6         com(a, b);
 7     }
 8 
 9     //@ ensures \result == (a + b) > (a / b);
10     public static boolean com(int a, int b) {
11         return (a*b) > (a/b);
12     }
13 
14 }

 

三、架构设计与迭代中的架构重构

 三次中的path均相同。数组存放节点,map存放不同节点及其出现次数,hashcode存放其hash值。

1 public class MyPath implements Path {
2 
3     private ArrayList<Integer> nodes;
4 
5     private HashMap<Integer, Integer> distinctNode;
6 
7     private Integer hashCode;
8 }

 

 MyPathContainer

两个正反向hashmap存放路径与其对应序号,keyGenerate用于生成路径编号,distinctNodeCount记录不同点个数

1 public class MyPathContainer implements PathContainer {
2 
3     private HashMap<Integer, Path> hashMap;
4     private HashMap<Path, Integer> reverseHashMap;
5 
6     private int keyGenerate;
7     private HashMap<Integer, Integer> distinctNodeCount;
8

 

MyGraph

添加AdjacencyList来处理图,其中adjacencyList为邻接表,而distance用来保存已经计算出结果的图的距离。

 1 public class MyGraph implements Graph {
 2 
 3     private HashMap<Integer, Path> hashMap;
 4     private HashMap<Path, Integer> reverseHashMap;
 5 
 6     private int keyGenerate = 0;
 7     private HashMap<Integer, Integer> distinctNodeCount;
 8 
 9     private AdjacencyList adjacencyList = new AdjacencyList();
10 }

 

 1 public class AdjacencyList {
 2 
 3     //fromNode, <toNode, time>
 4     private HashMap<Integer, HashMap<Integer, Integer>> adjacencyList
 5             = new HashMap<>();
 6 
 7     private boolean change = false;
 8 
 9     //fromNode, <toNode, distance>
10     private HashMap<Integer, HashMap<Integer, Integer>> distance
11             = new HashMap<>();
12 }

 

MyRaiwaySystem

进一步进行了AdjacencyList的拓展,完成了进行各个方面的图的建立,计算时在根据对应的图计算相应的结果。

 1 public class AdjacencyList {
 2     //fromNode, <toNode, time>
 3     private HashMap<Integer, HashMap<Integer, Integer>> distanceGraph
 4             = new HashMap<>();
 5     //fromNode, <toNode, distance>
 6     private HashMap<Integer, HashMap<Integer, Integer>> distance
 7             = new HashMap<>();
 8     private boolean distanceChange = false;
 9 
10     private HashMap<Integer, HashMap<Integer, PriorityQueue<Integer>>>
11             transferGraph = new HashMap<>();
12 
13     private HashMap<Integer, HashMap<Integer, PriorityQueue<Integer>>>
14             priceGraph = new HashMap<>();
15 
16     private HashMap<Integer, HashMap<Integer, PriorityQueue<Integer>>>
17             satisfyGraph = new HashMap<>();
18 
19     private HashMap<Integer, HashMap<Integer, Integer>> transfer
20             = new HashMap<>();
21 
22     private HashMap<Integer, HashMap<Integer, Integer>> price = new HashMap<>();
23 
24     private HashMap<Integer, HashMap<Integer, Integer>> satisfy
25             = new HashMap<>();
26 
27     private boolean transferChange = false;
28 
29     private boolean priceChange = false;
30 
31     private boolean satisfyChange = false;
32

四、分析bug与修复

在第一次作业中,抄一抄规格就平稳的度过了。

在第二次作业中,添加了比较复杂的求最短路径,本地进行了简单的测评,没有发现问题。

第三次作业就更加的复杂了,本地进行了较长时间的bug寻找,具体来讲就是各种笔误之类的问题。。。

所幸,在强测中没有发现问题。

 五、心得与体会

这一章节主要研究了一下JML这种规范化的语言,通过三次作业,能够基本上了解好这部分的内容。值得一提的是,在进行规范设计的同时,还进行了关于如何提高程序效率方面的探索。

在第二次作业中,就进行了关于效率的探索,使用类似于缓存的东西,计算一次之后将结果存储起来,在以后进行相同的计算时,可以直接进行读取,而不需要再次的遍历。

第三次作业更是将这种想法发挥到了顶峰。经过同学的讨论,大体上有两种想法,一种是进行点的拆分,另一种是对路径进行提前的路程计算,形成的图类似于完全图的想法。

相比于之前的作业,第三单元相对而言比较轻松(除去程序效率的讨论)。

 

posted @ 2019-05-22 20:54  zzx2017  阅读(135)  评论(0)    收藏  举报