一、规格化设计发展史
这个问题直接在网上搜索,甚至连相近问题的答案都搜不到。。看了下同学博客里的内容,大家调研到的基本都是软件设计的发展历史。与大多数事物的发展历史相同,程序设计的发展也是逐步完善,由不成熟变得成熟,由毫无章法变得有迹可循,也就是所谓的规格化设计。有了规格化设计,就相当于给程序员们一个规定,这让大家能相互读懂,入手对方的代码,利于合作与共同进步。
二、规格类BUG
BUG类型 | BUG对应行数 |
MODIFIES不完整 | 8 |
MODIFIES不完整 | 6 |
REQUIRES不完整 | 0 |
三、BUG产生原因
(1)第一个BUG是第十次作业被报的,MODIFIES不完整,出租车类的run方法里,对gui进行了设置,但是并没有在MODIFIES里写gui。
(2)第二个BUG是第十一次作业被报的,MODIFIES不完整,在SPFA方法里,将地图上的边存入边数组,该数组为类属性,未将数组写入MODIFIES里。
(3)第三个BUG也是第十一次作业被报的,REQUIRES不完整,等等BUG(陆续报了几个),都是因为,我在新加入一些类之后,有些方法忘记写JSF。
四、前置条件的不好写法与改进
(1)不好写法:
public static int sortedSearch (int[] a, int x) /**@ REQUIRES: (\all int i, j; i >0 && j>0); @ MODIFIES: None; @ EFFECTS: (\exist int k; a[k] == x) ==> \result == k ; (\all int k; a[k] != x) ==> \result == -1; */ { found = false; for(int i=a.length-1;i>=0;i--){ if(a[i] == x){ z = i; found = true; } if(found) return z; else return -1; } }
改进:
public static int sortedSearch (int[] a, int x) /**@ REQUIRES: (\all int i, j; 0 <= i < j < a.length; a[i] <= a[j]); @ MODIFIES: None; @ EFFECTS: (\exist int k; a[k] == x) ==> \result == k ; (\all int k; a[k] != x) ==> \result == -1; */ { found = false; for(int i=a.length-1;i>=0;i--){ if(a[i] == x){ z = i; found = true; } if(found) return z; else return -1; } }
(2)不好写法:
public void insert(BinarySortedTree tree, int x) /**@ REQUIRES: (tree != null); @ MODIFIES: tree; @ EFFECTS: (\old(tree) == null) ==> (tree.root == x); (\exist BinarySortedTree x_node in tree, (x_node.value == x) && ( (x_node.left.value != null) ==>( x_node.left.value <= x_node.value)) && ( (x_node.right.value != null) ==>( x_node.value <=x_node.right.value) ); */
改进:
public void insert(BinarySortedTree tree, int x) /**@ REQUIRES: (\all BinarySortedTree node in tree; node.left.value <= node.value <=node.right.value); @ MODIFIES: tree; @ EFFECTS: (\old(tree) == null) ==> (tree.root == x); (\exist BinarySortedTree x_node in tree, (x_node.value == x) && ( (x_node.left.value != null) ==>( x_node.left.value <= x_node.value)) && ( (x_node.right.value != null) ==>( x_node.value <=x_node.right.value) ); */
(3)不好写法:
public static void removeDupls(Vector v) /**@ REQUIRES: None ; @ MODIFIES: v; @ EFFECTS: (\all int i,j ; 0<=i<j<v.length; v.get(i) != v.get(j) ); (\all int i; 0<=i<\old(v).length; v.contains(\old(v).get(i))) ; */
改进:
public static void removeDupls(Vector v) /**@ REQUIRES: v != null ; @ MODIFIES: v; @ EFFECTS: (\all int i,j ; 0<=i<j<v.length; v.get(i) != v.get(j) ); (\all int i; 0<=i<\old(v).length; v.contains(\old(v).get(i))) ; */
(4)不好写法:
public static void addMax(Vector v, Integer x) throw NullPointerException, NotSmallException /**@ REQUIRES: (\all int i; 0<=i<v.length); @ MODIFIES: v; @ EFFECTS: normal_behavior (\all int i ; 0<=i<\old(v).length; \old(v).get(i).intValue <= x.intValue) ==> (v.size == \old(v).size+1) && (v.contains(x)) ; (\old(v) == null) ==> exceptional_behavior (NullPointerException); (\exist int i ; 0<=i<\old(v).length; \old(v).get(i).intValue > x.intValue) ==> exceptional_behavior (NotSmallException); */
改进:
public static void addMax(Vector v, Integer x) throw NullPointerException, NotSmallException /**@ REQUIRES: (\all int i; 0<=i<v.length; v.get(i) instanceof Integer); @ MODIFIES: v; @ EFFECTS: normal_behavior (\all int i ; 0<=i<\old(v).length; \old(v).get(i).intValue <= x.intValue) ==> (v.size == \old(v).size+1) && (v.contains(x)) ; (\old(v) == null) ==> exceptional_behavior (NullPointerException); (\exist int i ; 0<=i<\old(v).length; \old(v).get(i).intValue > x.intValue) ==> exceptional_behavior (NotSmallException); */
(5)不好写法:
public synchronized void setstatus(int i) { /** @REQUIRES:None; @MODIFIES: status; @EFFECTS: this.status == i; @THREAD_REQUIRES: \locked(this); @THREAD_EFFECTS: \locked(); @ */ status = i; }
改进:
public synchronized void setstatus(int i) { /** @REQUIRES: (\all integer i; 0 <= i <= 1); @MODIFIES: status; @EFFECTS: this.status == i; @THREAD_REQUIRES: \locked(this); @THREAD_EFFECTS: \locked(); @ */ status = i; }
五、后置条件的不好写法与改进
(1)不好写法:
public static int sortedSearch (int[] a, int x) /**@ REQUIRES: (\all int i, j; 0 <= i < j < a.length; a[i] <= a[j]); @ MODIFIES: None; @ EFFECTS: (\all int k; a[k] == x) ==> \result == k ; (\all int k; a[k] != x) ==> \result == -1; */ { found = false; for(int i=a.length-1;i>=0;i--){ if(a[i] == x){ z = i; found = true; } if(found) return z; else return -1; } }
改进:
public static int sortedSearch (int[] a, int x) /**@ REQUIRES: (\all int i, j; 0 <= i < j < a.length; a[i] <= a[j]); @ MODIFIES: None; @ EFFECTS: (\exist int k; a[k] == x) ==> \result == k ; (\all int k; a[k] != x) ==> \result == -1; */ { found = false; for(int i=a.length-1;i>=0;i--){ if(a[i] == x){ z = i; found = true; } if(found) return z; else return -1; } }
(2)不好写法:
public static void sort (int [ ] a) /**@ MODIFIES: a; @ EFFECTS: (0 <= i < j < a.length ==> a[i] <= a[j]); */
改进:
public static void sort (int [ ] a) /**@ MODIFIES: a; @ EFFECTS: (\all int i, j; 0 <= i < j < a.length; a[i] <= a[j]); */
(3)不好写法:
public void insert(BinarySortedTree tree, int x) /**@ REQUIRES: (\all BinarySortedTree node in tree; node.left.value <= node.value <=node.right.value); @ MODIFIES: tree; @ EFFECTS: (\old(tree) == null) ==> (tree.root == x); (\exist BinarySortedTree x_node in tree, (x_node.value == x) ); ( (x_node.left.value != null) ==>( x_node.left.value <= x_node.value) ); ( (x_node.right.value != null) ==>( x_node.value <=x_node.right.value) ); */
改进:
public void insert(BinarySortedTree tree, int x) /**@ REQUIRES: (\all BinarySortedTree node in tree; node.left.value <= node.value <=node.right.value); @ MODIFIES: tree; @ EFFECTS: (\old(tree) == null) ==> (tree.root == x); (\exist BinarySortedTree x_node in tree, (x_node.value == x) && ( (x_node.left.value != null) ==>( x_node.left.value <= x_node.value)) && ( (x_node.right.value != null) ==>( x_node.value <=x_node.right.value) ); */
(4)不好写法:
public static void removeDupls(Vector v) /**@ REQUIRES: v != null ; @ MODIFIES: v; @ EFFECTS: (0<=i<j<v.length; v.get(i) != v.get(j) ); (0<=i<\old(v).length; v.contains(\old(v).get(i))) ; */
改进:
public static void removeDupls(Vector v) /**@ REQUIRES: v != null ; @ MODIFIES: v; @ EFFECTS: (\all int i,j ; 0<=i<j<v.length; v.get(i) != v.get(j) ); (\all int i; 0<=i<\old(v).length; v.contains(\old(v).get(i))) ; */
(5)不好写法:
public static int min (int[ ] a) throws NullPointerException, EmptyException /**@ EFFECTS: normal_behavior \result == \min a; */
改进:
public static int min (int[ ] a) throws NullPointerException, EmptyException /**@ EFFECTS: normal_behavior \result == \min a; (a == null) ==> exceptional_behavior (NullPointerException); (a.length == 0) ==> exceptional_behavior (EmptyException); */
六、功能BUG与规格BUG联系
因为当时写的时候就是先写的代码,再补充的JSF,一般情况下,只要是代码逻辑上有错,JSF肯定是有错的。有时候功能上没有问题,但是JSF有些东西丢了也会导致JSF出错,这也是被报BUG的主要原因。。。
所以说,以后最好先写JSF再写代码,每次改代码记得更新JSF,MODIFIES里的内容千万不能忘!!
七、规格化设计思路与体会
至于思路:
写JSF的思路:
一看传入的参数,根据传入的参数还有代码的功能逻辑等写出前置条件中的内容;
二看代码里会修改的内容。包括对this的修改、对传入对象的修改、对环境对象的修改(如数据库、外接设备等)、对全局变量的修改。这些变量的修改都需要写到MODIFIES里。
三看执行后返回结果或系统状态应该满足的要求,也就是过程在所有未被前置条件排除的输入下给出的结果。
至于体会:
使用规格化设计方法,代码显得更加清晰美观,可读性大大增强。认真书写JSF对debug有一定的帮助。
为以后工程化打下良好的基础。