规格化设计的大致发展历史
由于计算机诞生之初,并没有编译器操作系统这一类东西,也没什么高级语言,那时的程序员只能使用机器语言来编写程序,后来为了方便程序员编写又出现了助记符也就是汇编语言。
程序设计语言的三次分离使软件技术产生飞跃
1950年代,第一次分离,主程序和子程序的分离
程序结构模型是树状模型,子程序可先于主程序编写。通过使用库函数来简化编程,实现最初的代码重用。产生基本的软件开发过程:分析—设计—编码—测试,使大型软件系统的开发成为可能
1975—1980年代,第二次分离,规格说明(Spec)和体(body)的分离
说明是类型定义和操作描述,体是操作的具体实现。(具体的例子就是C++,Java等面向对象语言的类说明与类实现的分离。)解决方案设计只关注说明,实现时引用或者设计体。体的更改、置换不影响规格说明,保证了可移植性。支持多机系统,但要同样环境。此时产生了划时代的面向对象技术。
1995—2000年代,第三次分离,对象使用和对象实现的分离
基于构件开发:标准化的软件构件如同硬件IC,可插拔,使用者只用外特性,不计内部实现。
Web Services:软件就是服务。分布式,跨平台,松耦合。
程序设计语言的第二次分离催生了规格化设计的诞生,规格化优点很多,故得到了人们的重视。
所被报告的规格bug
限于 bug树的限制,对手无法上报?不存在的。想方设法给您报上去。
作业9
无
作业10
作业11
规格bug产生的原因
1.规格这种东西不是应该先写了再实现函数体吗?第七次作业写了很多函数,第九次都要加上规格,自己不细心,总会有些遗漏的
2.新作业,新的需求,要改的函数有些多,自己不细心,总会有些遗漏的
3.对规格的要求理解不全面,自己不细心,总会有些遗漏的要求
4.测试者严以待人,我宽以待己,总会有些没见过的规格要求
前置条件
不好写法:
1.没有指定范围
@REQUIRES:i instanceof int && j instanceof int
2.没有指定范围
@REQUIRES:c instanceof Coordinate
3.逻辑优先级不对
@REQUIRES:num instanceof int&& num==1||num==3
4.=应为==
@REQUIRES:x=(xi,xj),y=(yi,yj);0<=xi<80&&0<=xj<80&&0<=yi<80&&0<=yj<80
5.类型描述不好
@REQUIRES:taxis instanceof Taxi[]
改进写法:
1.
@REQUIRES:i instanceof int && j instanceof int && 0<=i<80 && 0<=j<80
2.
@REQUIRES:c instanceof Coordinate && 0<=c.i<80 && 0<=c.j<80
3.
@REQUIRES:num instanceof int && (num==1||num==3)
4.
@REQUIRES:x==(xi,xj),y==(yi,yj);0<=xi<80&&0<=xj<80&&0<=yi<80&&0<=yj<80
5.
@REQUIRES:all int i;0<=i<taxis.length;taxis[i] instanceof Taxi
后置条件
不好写法:
1.初始化用自然语言
@EFFECTS:
initialize the new Taxi
2.没有对异常行为进行说明
@EFFECTS: norma_behavior( esult == selectdire.get(Rand(0,selectdire.size)));
3.没有使用old
@EFFECTS:
esult == true;responlist.size == responlist.size+1;responlist.contains(num));
4.过于简略
@EFFECTS:set the graph
改进写法:
1.
@EFFECTS: this.taxinum == taxinum; this.position == TaxiRandom.getPosition(80); this.credit == 0; this.dire == RoadPlan.DirectionSeek(80, this.position); this.status == TaxiStatus.Waiting; this.statusnum == 2; this.psg == null;
2.
@EFFECTS: norma_behavior( esult == selectdire.get(Rand(0,selectdire.size))); exception_behavior(throw IllegalArgumentException)
3.
@EFFECTS: esult == true;responlist.size == old(responlist).size+1;responlist.contains(num));
4.
@EFFECTS: all int i,j;0<=i<Map.map.length&&0<=j<Map.map[i].lenght;Map.map[i][j] == 1 || Map.map[i][j] == 3 ==> Map.graph[i * 80 + j][i * 80 + j + 1] == true;Map.graph[i * 80 + j + 1][i * 80 + j] == true; all int i,j;0<=i<Map.map.length&&0<=j<Map.map[i].lenght;Map.map[i][j] == 2 || Map.map[i][j] == 3 ==> Map.graph[i * 80 + j][(i + 1) * 80 + j] == true;Map.graph[(i + 1) * 80 + j][i * 80 + j] == true;
功能bug与规格bug
功能bug和规格bug似乎没有很直接的聚集关系,毕竟我们的流程是写了函数才加的规格,出现规格bug大概是方法修改后规格改得不仔细。但是,越长的函数确实是越可能既出现规格bug又出现功能bug的。
设计规格和撰写规格的基本思路和体会
首先想想方法的应用场景和方法内实现功能的要求,确定方法的Require,确定方法参数的范围;
细化方法要实现的功能,确定方法会更改的属性,确定Modifies;
根据已有函数编写EFFECTS,我想大家可能都是这样的吧,先实现了功能再来写规格,但课程的设置就会导致这样的结果,我觉得是作业的一大缺陷之一,并不是很符合设计规格和撰写规格的流程。
测试者对规格的要求千变万化,有时候测试者自己都不动脑子,None有没有写也要扣,System.out也说要加入Modifies,非要助教给了答复才撤销。
我不是针对谁,我是说这种就是垃圾。
我觉得作业上规格带给我的收获远远不如实验课上那两个多小时来得多,作业的规格费时费心,互测上还让人不开心,(互测使人抑郁也是赖不着课程组的)。
老师也说了,IFTTT这次作业可有可无?为啥不用这次作业来好好地训练一下规格化的思想?
这三次OO互测的体会
谁爱开心谁开心