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 规格优化
前置条件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public synchronized void setCredit(int i) { /** * @REQUIRES: * @MODIFIES: his.credit; * @EFFECTS: his.credit==old( his.credit)+i; * @THREAD_REQUIRES: * @THREAD_EFFECTS: locked(); */ credit+=i; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public synchronized void setCredit(int i) { /** * @REQUIRES: i+old( his.credit)>=0; * @MODIFIES: his.credit; * @EFFECTS: his.credit==old( his.credit)+i; * @THREAD_REQUIRES: * @THREAD_EFFECTS: locked(); */ credit+=i; }
后置条件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; his.reqlist.contains(r);r.src==src && r.dst==dst && r.time==reqtime) ==> esult==true; * (all Request r; his.reqlist.contains(r);!(r.src==src && r.dst==dst && r.time==reqtime)) ==> esult==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; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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: esult==true ==> (exist Request r; his.reqlist.contains(r);r.src==src && r.dst==dst && r.time==reqtime); * esult==false==> (all Request r; his.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; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private Taxi chooseTaxi() { /** * @REQUIRES: respondTaxi!=null; * @MODIFIES: None; * @EFFECTS: * (all Taxi taxi; his.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)); * esult==taxi_chosen; */ int maxcredit=0,mindistance=1000000; Taxi taxi_chosen=null; WriteFile(true,"***Respond Taxi Information "); 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; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private Taxi chooseTaxi() { /** * @REQUIRES: respondTaxi!=null; * @MODIFIES: None; * @EFFECTS: * (all Taxi taxi; his.respondTaxi.contains(taxi);taxi.credit< esult.credit * || (taxi.credit== esult.credit && distance between esult and src is smaller than distance between taxi and src)); */ int maxcredit=0,mindistance=1000000; Taxi taxi_chosen=null; WriteFile(true,"***Respond Taxi Information "); 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; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public long getTime() { /** * @REQUIRES: * @MODIFIES: None; * @EFFECTS: esult= his.time; */ return time; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public long getTime() { /** * @REQUIRES: * @MODIFIES: None; * @EFFECTS: esult== his.time; */ return time; }
PART5 设计规格和撰写规格的体会
到目前为止依然是先写代码再写规格,和老师的要求是反着的orz……后面会努力改过来
刚开始写规格的时候基本上EFFECTS用的都是自然语言,因为不能够抽象出这段代码的逻辑影响。在第10,11节课讲完以后,受到课上PPT中示例的启发,逐渐能够用
布尔表达式等相对规范的方法进行JSF书写。
说真的刚开始觉得这个很鸡肋,很麻烦,但是中间隔了很长的时间没有看自己的代码,回来直接看规格,嘿,瞬间理清了自己代码,感觉不错,慢慢地开始对规格撰写这件事有了改观。
现在还在入门级,境界不够,所以如此感受不到规格设计的重要性……希望经过不断锤炼,自己能领悟个中真谛吧~