OO第三单元总结来了,主要针对规格化设计展开~
PART I 规格化设计发展史
大规模复杂系统开发,需要建立程序设计者和使用者的桥梁(契约关系???),同时保证程序的正确性及减少软件错误。
>>1950年代——主程序和子程序的分离
>>1975-1980——规格说明和体的分离
>>1995-2000——对象使用个对象实现的分离
规格化设计逐渐得到人们的重视,分析其原因主要有:
1. 开发者准确实现需求
2. 团队开发大型工程时,成员正确理解、调用对方代码
(3. 学校教学时的注重)
PART2 bug分析
PART3 功能bug与规格bug的聚焦关系
第9次功能bug是车随机行驶会掉头,本质是flow计算的问题
第11次bug是load发出多个请求,读入不是同一时间,同质请求判断不全
这两个bug和规格bug没有聚集关系。
(开始胡扯:个人认为,我们作业中宏观显示出来有聚集关系,一部分原因是,佛系测试者本来就佛系测功能,规格bug自然也报的少,另外的一些测试者,比较认真,测功能比较全面,规格检查也比较全面,所以两种bug同比增长…………)
PART4 规格优化
前置条件
public synchronized void setCredit(int i) { /** * @REQUIRES: * @MODIFIES: \this.credit; * @EFFECTS: \this.credit==\old(\this.credit)+i; * @THREAD_REQUIRES: * @THREAD_EFFECTS: \locked(); */ credit+=i; }
public synchronized void setCredit(int i) { /** * @REQUIRES: i+\old(\this.credit)>=0; * @MODIFIES: \this.credit; * @EFFECTS: \this.credit==\old(\this.credit)+i; * @THREAD_REQUIRES: * @THREAD_EFFECTS: \locked(); */ credit+=i; }
后置条件
private synchronized boolean judgeSame(Point src,Point dst,long reqtime) { /** * @REQUIRES: src!=null && dst!=null; * 0<=src.x,src.y,dst.x,dst.y<80; * @MODIFIES: None; * @EFFECTS: (\exist Request r;\this.reqlist.contains(r);r.src==src && r.dst==dst && r.time==reqtime) ==> \result==true; * (\all Request r;\this.reqlist.contains(r);!(r.src==src && r.dst==dst && r.time==reqtime)) ==> \result==false; * @THREAD_REQUIRES: * @THREAD_EFFECTS: \locked(); */ for(int i=0;i<reqlist.size();i++) { Request req=reqlist.get(i); if(req.getSrc().equals(src) && req.getDst().equals(dst) && req.getTime()==reqtime) { System.out.println("#SAME Request"); return true; } } return false; }
private synchronized boolean judgeSame(Point src,Point dst,long reqtime) { /** * @REQUIRES: src!=null && dst!=null; * 0<=src.x,src.y,dst.x,dst.y<80; * @MODIFIES: None; * @EFFECTS: \result==true ==> (\exist Request r;\this.reqlist.contains(r);r.src==src && r.dst==dst && r.time==reqtime); * \result==false==> (\all Request r;\this.reqlist.contains(r);!(r.src==src && r.dst==dst && r.time==reqtime)) ; * @THREAD_REQUIRES: * @THREAD_EFFECTS: \locked(); */ for(int i=0;i<reqlist.size();i++) { Request req=reqlist.get(i); if(req.getSrc().equals(src) && req.getDst().equals(dst) && req.getTime()==reqtime) { System.out.println("#SAME Request"); return true; } } return false; }
private Taxi chooseTaxi() { /** * @REQUIRES: respondTaxi!=null; * @MODIFIES: None; * @EFFECTS: * (\all Taxi taxi;\this.respondTaxi.contains(taxi);taxi.credit<taxi_chosen.credit * || (taxi.credit==taxi_chosen.credit && distance between taxi_chosen and src is smaller than distance between taxi and src)); * \result==taxi_chosen; */ int maxcredit=0,mindistance=1000000; Taxi taxi_chosen=null; WriteFile(true,"***Respond Taxi Information\r\n"); for(Taxi taxi: respondTaxi) { WriteFile(true,taxi.toString()); Point taxiloc=taxi.getLoc(); if(!taxi.getTaxiState().equals(TaxiState.wait)) { continue; } int taxi_credit=taxi.getCredit(); int type=1; if(taxi instanceof Taxi_special) type=2; int taxi_src=map.FindPath(taxiloc.x,taxiloc.y,src.x,src.y,type).size(); if(taxi_credit>maxcredit || (taxi_credit==maxcredit && taxi_src<mindistance)) { maxcredit=taxi_credit; mindistance=taxi_src; taxi_chosen=taxi; } } return taxi_chosen; }
private Taxi chooseTaxi() { /** * @REQUIRES: respondTaxi!=null; * @MODIFIES: None; * @EFFECTS: * (\all Taxi taxi;\this.respondTaxi.contains(taxi);taxi.credit<\result.credit * || (taxi.credit==\result.credit && distance between \result and src is smaller than distance between taxi and src)); */ int maxcredit=0,mindistance=1000000; Taxi taxi_chosen=null; WriteFile(true,"***Respond Taxi Information\r\n"); for(Taxi taxi: respondTaxi) { WriteFile(true,taxi.toString()); Point taxiloc=taxi.getLoc(); if(!taxi.getTaxiState().equals(TaxiState.wait)) { continue; } int taxi_credit=taxi.getCredit(); int type=1; if(taxi instanceof Taxi_special) type=2; int taxi_src=map.FindPath(taxiloc.x,taxiloc.y,src.x,src.y,type).size(); if(taxi_credit>maxcredit || (taxi_credit==maxcredit && taxi_src<mindistance)) { maxcredit=taxi_credit; mindistance=taxi_src; taxi_chosen=taxi; } } return taxi_chosen; }
public long getTime() { /** * @REQUIRES: * @MODIFIES: None; * @EFFECTS: \result=\this.time; */ return time; }
public long getTime() { /** * @REQUIRES: * @MODIFIES: None; * @EFFECTS: \result==\this.time; */ return time; }
PART5 设计规格和撰写规格的体会
到目前为止依然是先写代码再写规格,和老师的要求是反着的orz……后面会努力改过来
刚开始写规格的时候基本上EFFECTS用的都是自然语言,因为不能够抽象出这段代码的逻辑影响。在第10,11节课讲完以后,受到课上PPT中示例的启发,逐渐能够用
布尔表达式等相对规范的方法进行JSF书写。
说真的刚开始觉得这个很鸡肋,很麻烦,但是中间隔了很长的时间没有看自己的代码,回来直接看规格,嘿,瞬间理清了自己代码,感觉不错,慢慢地开始对规格撰写这件事有了改观。
现在还在入门级,境界不够,所以如此感受不到规格设计的重要性……希望经过不断锤炼,自己能领悟个中真谛吧~