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这种规范化的语言,通过三次作业,能够基本上了解好这部分的内容。值得一提的是,在进行规范设计的同时,还进行了关于如何提高程序效率方面的探索。
在第二次作业中,就进行了关于效率的探索,使用类似于缓存的东西,计算一次之后将结果存储起来,在以后进行相同的计算时,可以直接进行读取,而不需要再次的遍历。
第三次作业更是将这种想法发挥到了顶峰。经过同学的讨论,大体上有两种想法,一种是进行点的拆分,另一种是对路径进行提前的路程计算,形成的图类似于完全图的想法。
相比于之前的作业,第三单元相对而言比较轻松(除去程序效率的讨论)。

浙公网安备 33010602011771号