一、规格化设计发展历史
程序规格化设计对于代码编写的规范能够让程序变得更加易懂,能让使用者更加轻松简单的学会如何正确使用这段程序,可以让软件设计者和真正写程序的人员之间进行有效的沟通。此外,通过规格的抽象和总结,使用者能够直接使用这段程序而免去浪费大量时间来看懂代码的痛苦过程。更重要的是,代码的维护变得更加简单。结构化分析在1980年代起开始广为使用。结构化分析包括将系统概念转换为用数据及控制的来表示。数据字典用来描述数据和指令的流动,而用程序规格来描述交易或数据转换的相关信息。结构化分析是许多结构化方法中的一部分。“结构化分析是系统分析、设计及编程技术的组合,其目的是为了处理1960至1980年软件开发所遇到的问题,也没有将需求及设计文件化的技术。但是随着系统越来越大也更加复杂,信息系统的发展也变得越来越困难。”为了方便管理大而复杂的系统,慢慢演进了更多的结构化方法。80年代后,面向对象的设计兴起,相比于单纯的结构化设计,面向对象的设计从审视问题的角度上就有了差异,程序发生了从围绕“行为”执行到围绕“客体”执行的变化,随之而来的,就是封装性地提高,可重用性的提高,可以说,面向对象进一步实现了结构化设计,是结构化设计更进一步的实现。
二、规格bug及产生的原因
我这几次作业规格中存在的bug主要都是由于我自己的懒惰所造成的。因为我的代码中具有很多的方法(大约200),所以要对每一个方法都详细的去写规格需要花费较多的时间和精力,所以,对于其中一些比较简单的方法,我便没有去写规格,所以被互测的同学找了出来,扣了很多分。
另外,对于一些较为复杂的方法,我不知道如何去准确的书写effects部分的jsf。因为这些方法往往具有很多功能,写的不好的话,要么不能准确概括函数的功能,要么太过于冗长。反正我觉得书写一个好的规格是很不容易的。
三、改进
1.
/** * @REQUIRES: None; * @MODIFIES: None; * @EFFECTS: None; */ public synchronized String toString(){ String s=new String(); s+="出租车编号:"+this.code+"\r\n"; s+="车辆位置:"+"("+this.x_position+","+this.y_position+")\r\n"; s+="车辆状态:"+this.status+"\r\n"; s+="车辆信用:"+this.credit+"\r\n"; return s; }
EFFECTS表示执行后返回结果或系统状态应该满足的要求,该方法有返回值,应加上\result==s;
2.
/** * @REQUIRES: 0<=x<6400 && 0<=y<6400 * @MODIFIES : None; * @EFFECTS : None; */ public synchronized int getflow(int x,int y){ return this.nowflow[x][y]; }/** * @REQUIRES: 0<=x<6400 && 0<=y<6400 * @MODIFIES : None; * @EFFECTS : None; */ public synchronized int getflow(int x,int y){ return this.nowflow[x][y]; }
该方法对整个方法进行同步控制,需要加上@THREAD_EFFECTS: \locked()
3.
/** * @REQUIRES: None * @MODIFIES : this; * @EFFECTS : None; */ public synchronized void addflow(int x,int y){ this.nowflow[x][y]++; this.nowflow[y][x]++; }
这里面x和y都是数组的索引,所以是有范围的,应该加上 0<=x<6400 && 0<=y<6400
4.
/** * @REQUIRES: None; * @MODIFIES: None; * @EFFECTS: 返回x,y中较小的值 */
不应该使用自然语言,改为:
/** * @REQUIRES: None; * @MODIFIES: None; * @EFFECTS: (x>=y) ==> \result = y; * (x<y) ==> \result = x; */
5.
/** * @REQUIRES: status!=null; * @MODIFIES : None; * @EFFECTS : None; */ public void searchStatus(String status){ TaxiStatus ts; switch(status){ case "WaitService": ts=TaxiStatus.WaitService; break; case "StopService": ts=TaxiStatus.StopService; break; case "GetOrder": ts=TaxiStatus.GetOrder; break; case "InService": ts=TaxiStatus.InService; break; default: System.out.println("hhh输入不合法!"); return; } for(int i=0;i<taxiset.size();i++){ tracetaxi temp=taxiset.get(i); if(temp.GetStatus()==ts) System.out.print(temp.code+" "); } System.out.println(" "); }
这里面,我对taxiset进行了修改,但是没有在modifies中写明。应在modifies中加入taxiset
四、总结
总的来说,这三次作业是在前面一次基础上进行扩展修改,增加一些新的功能,考察的是我们重构代码的能力。另外,本专题着重训练了我们关于规格的书写。这是我们在之前编写程序的时候没有注意的,规格就是一个程序,一个方法的说明书,在我们日后写大型工程中具有重要的意义。但是,在实际书写时,由于工作量太大的原因,导致许多地方是真的不想写jsf。另外,互侧时过于注重规格,所以引起了很大的争议,也感受到同学们的险恶之处,有的同学的恶意扣分更是让我感到恶心,甚至有些人将从别人哪里受得气发泄到另外的人身上。面向运气编程说的一点也不错,有的人会碰到疯狂扣规格的人,有的人运气好,会遇到不怎么看规格的人,所以在得分上具有很大的不公平性。