(一)规格化设计的发展编程
人们在脱离了面向机器的语言,建立了当时看来更高级的面向过程的语言后,大大地提高了编程效率,但一些面向过程的语言中的goto语句极大地限制了程序的规模。规格化程序设计采用子程序(好比函数)、代码区块、for循环以及while循环等结构来替换传统的goto,以此来改善计算机程序的明晰性、质量以及开发时间。dom
随着计算机硬件的飞速发展,应用复杂度愈来愈高,原有的程序开发方法已经愈来愈不能知足人们的需求。19世纪60年代爆发了表现为软件质量低下、项目没法如期完成、项目严重超支等状况的软件危机。模块化
通过一段时间的探索,人们提出了“规格化程序设计”来解决软件危机。1968年戴克斯特拉发表了著名的《GOTO有害论》,引发了人们多方的探讨,在这个过程当中,规格化程序设计方法诞生。与此同时,第一个结构化的程序语言Pascal诞生,并迅速流行。函数
规格化程序设计的主要特色是抛弃 goto 语句,采起“自顶向下、逐步细化、模块化”的指导思想。规格化程序设计经过“自顶向下、逐步细化、模块化”的方法,将软 件的复杂度控制在必定范围内,从而从总体上下降了软件开发的复杂度。结构化程序方法成为了 1970 年 代软件开发的潮流。测试
(二)规格BUGui
没有被报规格bug,多是测试者偷懒,又或者测试者也坚决地维护和谐六系。可是不报不等于没有,我的检查发现的bug仍是有。好比有两个方法的规格是用天然语言写的。以及,存在不规范的使用现象。this
(三)规格BUG产生的缘由spa
一、诚如老师所言,许多方法都是先写了代码,再回头写的规格,因此有差错;debug
二、对于JSF规范的掌握不够牢固,不少时候写的时候还要对照回去,致使出现语法的错误;设计
三、规格实际上是为了写好代码服务的,但代码以及写好了,再回头写规格,有种多余之感,认识上的偏差;
四、某些状况不知道如何表达,展开又过于庞大,只好用天然语言代替。
(四)错误写法和改进
@REQUIRES:
一、偷懒型
public Taxi(int i,TaxiGUI g,mapInfo map,int _type);
/** * @REQUIRES:Null * @MODIFIES:this.num * this.state * this.waitTime * this.credit * this.rtime * this.gui * this.taxiCoordinate[0] * this.taxiCoordinate[1] * this.m * @EFFECTS: this.num=i; * this.state=2; * this.waitTime=0; * this.credit=0; * this.rtime=0; * this.gui=g; * this.taxiCoordinate[0]=new Random().nextInt(80); * this.taxiCoordinate[1]=new Random().nextInt(80); * this.m=map; */
显然在这个构造器中,对于输入的出租车编号以及地图是有要求的,无脑写Null,就为了简化工做量。
改进:
public Taxi(int i,TaxiGUI g,mapInfo map,int _type); /** * @REQUIRES:(0<=i<80 && map is Connecting diagram) * @MODIFIES:this.num * this.state * this.waitTime * this.credit * this.rtime * this.gui * this.taxiCoordinate[0] * this.taxiCoordinate[1] * this.m * @EFFECTS: this.num=i; * this.state=2; * this.waitTime=0; * this.credit=0; * this.rtime=0; * this.gui=g; * this.taxiCoordinate[0]=new Random().nextInt(80); * this.taxiCoordinate[1]=new Random().nextInt(80); * this.m=map; */
二、自创符号代替规范语法型
public void setCoordinate(int x,int y) ; /** * @REQUIRES:0<=x<80, 0<=y<80 * @MODIFIES:this.taxiCoordinate * @EFFECTS:set the taxi's coordinate to be(x,y) */
其中 “,” 是做者本身想固然使用的表达而且的符号,应该替换为 “&&”
改进:
public void setCoordinate(int x,int y) ; /** * @REQUIRES:0<=x<80 && 0<=y<80 * @MODIFIES:this.taxiCoordinate * @EFFECTS:set the taxi's coordinate to be(x,y) */
三、天然语言型:
public synchronized int [][] getto(int[] coordinate,Order o,int sta) ; /** * @REQUIRES:\exist coordinate in map * \exist o * @MODIFIES:coordinate,state * @EFFECTS:set the taxi to coordinate * record the pass point information in o */
显然是假装成正确语法的天然语言
public synchronized int [][] getto(int[] coordinate,Order o,int sta) ; /** * @REQUIRES:map.contains(coordinate) * o!=Null * @MODIFIES:coordinate,state * @EFFECTS:set the taxi to coordinate * record the pass point information in o */
四、不完整型
public Order(int scx,int scy,int dcx,int dcy,Taxi[] t,int ind); /** * @REQUEST:0<=scx,scy,dcx,dcy<80 * @MODIFIES:Order * @EFFECT:initial the order */
对照代码我发现其实实现的功能中对参数的要求不止于此,还有对于t以及ind的要求
public Order(int scx,int scy,int dcx,int dcy,Taxi[] t,int ind){ /** * @REQUEST:0<=scx,scy,dcx,dcy<80 && t!=null && 0<=ind<100 * @MODIFIES:Order * @EFFECT:initial the order */
五、忘写型
public void SetarriveSrctime(long t) ; //空空如也
改正:
public void SetarriveSrctime(long t) ; /** * @REQUIRES:None * @MODIFIES:arriveSrctime * @EFFECTS:arriveSrctime=t */
@EFFRCTS:(同上)
一、偷懒型:
public void SetarriveSrctime(long t) ; /** * @REQUIRES:None * @MODIFIES:arriveSrctime * @EFFECTS:None
Modifiels都说有改动,而后骗我说EFFECTS没有
public void SetarriveSrctime(long t) ; /** * @REQUIRES:None * @MODIFIES:arriveSrctime * @EFFECTS:arriveSrctime=t */
二、自创符号型:
public int[] getDstCoordinate() ; /** * @REQUIRES:None * @MODIFIES:None * @EFFECTS:\result=dstCoordinate */
不应是“=”,而是“==”
public int[] getDstCoordinate() { /** * @REQUIRES:None * @MODIFIES:None * @EFFECTS:\result==dstCoordinate */
三、天然语言型:
public Order(int scx,int scy,int dcx,int dcy,Taxi[] t,int ind); /** * @REQUEST:0<=scx,scy,dcx,dcy<80 && t!=null && 0<=ind<100 * @MODIFIES:Order * @EFFECT:initial the order */
多是由于规范写的话,要写的太多了吧
public Order(int scx,int scy,int dcx,int dcy,Taxi[] t,int ind){ /** * @REQUEST:0<=scx,scy,dcx,dcy<80 && t!=null && 0<=ind<100 * @MODIFIES:Order * @EFFECT: * this.srcCoordinate[0]=scx; * this.srcCoordinate[1]=scy; * this.dstCoordinate[0]=dcx; * this.dstCoordinate[1]=dcy; * this.ordtime=System.currentTimeMillis()/500*500; */
四、不完整型
public void iteration() ; /** * @REQUIRES:NONE * @MODIFIES:None * @EFFECTS: * (type==1)==>\result==iter */
事实上,还有一个分支条件
public void iteration() { /** * @REQUIRES:NONE * @MODIFIES:None * @EFFECTS:
* (type!=1)==>\result=="the taxi is not vip!" * (type==1)==>\result==iter */
五、忘写型
public void SetarriveSrctime(long t) ; //空空如也
改正
public void SetarriveSrctime(long t) ; /** * @REQUIRES:None * @MODIFIES:arriveSrctime * @EFFECTS:arriveSrctime=t */
(五)功能BUG和规格BUG的汇集关系
序号 | 功能BUG | 出现BUG的方法 |
1 | 边界的出租车在判断流量是忘记越界问题,致使CRASH | Taxi类,getto函数 |
2 | 车辆回头现象 | 流量的刷新时间与车辆运行时间不协调 |
(六)心得体会
一、在写代码的时候,应该提早想好本身想要实现什么,如何实现,一个方法须要哪些数据,他会对个人类产生什么样的影响,这样写出来的代码有据可循,不管是debug仍是未来改动都会方便得多;
二、撰写JSF能够很好地表现一个方法的特性,就像是这个方法的使用说明书,也是编程者的生产设计图。不管是本身再看代码,或者其余使用者使用你的方法,都会十分便捷。