OO第三阶段总结
Posted nipo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OO第三阶段总结相关的知识,希望对你有一定的参考价值。
一、规格化设计
规格就是对一个方法/类/程序的外部可感知行为的抽象化表示,忽略实现的具体细节,使得设计与实现有效的分离开来。规格化设计的实现依赖于抽象化(Abstraction),包括过程抽象,数据抽象等等。使用规格化设计带来的好处就是减少了程序的复杂度,使得程序员可以专注于处理少数重要的部分,而不是钻牛角尖似的纠结于程序细节问题,提高编程的效率和安全性。
使用规格化编程可以大大提高编程质量。首先,提高了程序的可读性,类的每一个方法都明确的给出了方法的功能与对数据的影响,使得代码的使用者可以不必阅读繁琐的代码信息,只需要通过阅读方法规格就可以详细的了解方法的所有信息,这在团队合作中非常有效。其次,规格化编程可以提高程序的安全性。在具体实现一个方法之前,先用规格化对方法进行描述,相当于一个自我的逻辑纠错过程,避免了许多逻辑上的安全性漏洞,而且有了方法规格之后,程序的编写就变得更加行云流水了。
二、规格BUG
有幸这几次作业都没有被报规格上的BUG,也没有逐个深究其他人规格上的BUG,但是,通过与其他人的讨论以及对自己和被测者规格的检查,可以发现一些大家在规格上的共性的问题。
一个是偷懒。最明显的就是以下这种:
/** *@REQUIRES: None; *@MODIFIES: None; *@EFFECTS: None; */
而这段注释下面跟着的是一段十分冗长的代码,总不能什么事都不干吧。明显就是偷懒行为。
第二个就是纯自然语言描述,并没有使用规定的JSF语言。纯自然语言固有的问题就是容易产生逻辑上的漏洞也就是歧义,如果规格使用纯自然语言描述的话,自己读的很顺畅,但可能partner来阅读这段规格就“丈二和尚摸不着头脑”,给整个团队带来麻烦,所以,规格的描述应该尽量减少纯自然语言的使用,只有那些十分复杂,用JSF语言描述不了的方法,才使用自然语言,但问题来了,一个规格化设计的程序不应该出现及其复杂的代码,这就陷入了先有蛋还是先有鸡的逻辑怪圈了。
三、规格的改进
例1
/** * @REQUIRES:None; * @MODIFIES: None; * @EFFECTS: * \result == (与(X,Y)相连的顶点个数大于2); */
这是一段判断一个路口可不可以设置红绿灯的规格,可以发现后置条件直接使用自然语言描述,其实是不必要的,可以使用JSF语言来进行描述,修改后如下:
*@EFFECTS: *int i == ((x,y+1).connects(x,y)) + ((x,y-1).connects(x,y)) + *((x+1,y).connects(x,y)) + ((x-1,y).connects(x,y)); *\result == (i >= 3);
例2
/** * @REQUIRES:(dst!=null && 0<=root<6400); * @MODIFIES: None; * @EFFECTS: * \result == path; */
这是一段获取最短路径的规格,在后置条件里很突兀的出现了一个变量path,很明显没有对path进行描述,更改后如下:
*@EFFECTS: (\result!=null) ==> (\result[0] == start) &&(\result[\result.length1]==end) && (\all int i; 0<=i<\result.length-1; this.connects(\result[i], \result[i+1])) && (\all List<Node> p; p[0]==start && p[p.length-1]==end && \all int j; 0<=j<p.length-1; this.connects(p[j], p[j+1]) && p.length >=\result.length) */
直接对result进行描述,在逻辑上清晰了许多。
例3
/** * @REQUIRES:(path!=null); * @MODIFIES:map; * @EFFEETS: * (path对应文件存在) ==> (map[][]各元素置为读入的数字); */
这是摘取字读取地图文件的规格,明显前置条件描述并不全面,缺少了对地图文件内容的限制,修改后如下:
/** *@REQUIRES:(new File(path)).isFile && (new File(path)).line == 80 && (new File(path)).column == 80 && (new File(path)).words.isDigit;
通过路径获取到的文件的行数列数都应该是80,而且所有的字符都应该是数字。
四、功能BUG与规格BUG千丝万缕的联系
经过这几次作业的练习,确实发现了规格对编程的助力,但许多方法的实现仍沿用了老的思路,规格也算是蒙混过关吧,写完方法之后才写的规格,这导致了许多问题,反思这些问题,总能在规格上找到影子。
整理了这张表,记录下这些联系。
方法名 | 规格BUG | 功能BUG |
public void readFile(String filepath) | 使用自然语言描述后置条件 | 读取新的地图文件时会报错 |
private int[][] branch() | 规格描述不全面,忽略了功能细节 | 根据流量选择道路时出现了问题 |
五、感想与体会
这三次作业的练习,获益良多,认识到了抽象化在程序设计中的重要意义,也体会到了应用规格后在编写程序方面的助力,但明显感觉到的问题就是,规格化设计虽好,但给每个类写上规格,就会使编程效率大大降低,算是喜忧参半吧,可能这也是规格化设计应用的局限之处,但对个人编程以及团队编程来说,给一些对项目实现极其重要的方法写上规格,确实能大大提高项目的可靠性,这对以后的编程给出了很好的思路。
以上是关于OO第三阶段总结的主要内容,如果未能解决你的问题,请参考以下文章