OO第三次阶段性总结
一、规格化设计的历史以及人们重视的原因
发展历史
从20世纪60年代开始,就存在着许多不同的形式规格说明语言和软件开发方法。在形式规格说明领域一些最主要的发展过程列举如下:
1969-1972 C.A.R Hoare撰写了"计算机编程的公理基础(An Axiomatic Basis for Computer Programming)"和"数据表示的正确性证明"两篇开创性的论文,并提出了规格说明的概念。
1974-1975 B.Liskow/S.N. Zilles和J. Guttag引入了"抽象数据类型"的概念。
1976 E.W. Dijkstra定义了"最弱前置条件"的概念
1977 R.Burstall和J.Goguen提出了第一个代数规格说明语言:Clear
1988 Standford的SRI开发了代数规格说明语言OBJ3
1980-1986 C.Jones定义了VDM语言,也就是维也纳开发方法。
1985-1992 牛津大学的程序研究小组开发了Z规格说明语言。与此同时BP研究室开发了称之为B方法的面向模型的规格说明语言。
1985-1993 在MIT和Digital SRC开发了代数规格说明语言Larch
从1991年开始,面向对象的形式规格说明语言开始发展,例如,Object-Z, VDM++, CafeOBJ等语言。
1996-2000年 在欧洲CoFI(Common Framework Initiative)项目资助下开发"统一"代数规格说明语言CASL(Common Algebraic Specification Language)
重视原因
我认为规格首先给了大家编程时一个统一的认识,明确了程序运行的前提和程序运行后的效果,这一点在个人编程中有助于理清思路,而在集体的工程开发过程中也有助于协作,使大家开发的方向一致。
另一方面我认为正确的规格可以方便编程者进行调试,通过断言判断前置条件是否满足以及检验后置条件是否在程序运行后满足。
二、规格Bug数量及原因分析
| 作业 | Bug类型及细节 | 所在文件及行数 |
| 第九次 | 无 | 无 |
| 第十次 | Effects内容为实现算法:\result写成了\return | 很多文件中 |
| 第十一次 | Effects不完整:在有try-catch的方法中忘记写exceptional_behavior | InputHandler.java/192 |
规格bug原因分析:第九次没有被报规格bug,大概是测试者不太关心。第十次和第十一次作业中都是有所疏忽导致。其中第十次作业是一个笔误,几乎所有文件都写成了\return==balabala,第十一次作业中有一个方法由于后来有改动,没有添加exceptional_behavior。
三、不好的规格写法及改进
前置条件
1. 自然语言描述
/**
* @REQUIRES: k存在
* @MODIFIES: v
* @EFFECTS: v == \old(v) + 1;
*/
不好
/**
* @REQUIRES: k != null
* @MODIFIES: v
* @EFFECTS: v == \old(v) + 1;
*/
好
2. 不是布尔表达式
/**
*
* @REQUIRES:
* this.taxiStatus = IDLE;
* @MODIFIES:
* this.credit;
* @EFFECTS:
* this.credit = \old(this.credit) + 1;
* (\all PassengerRequest r in range, r.grabbedByTaxi(this))
*
*/
不好
/**
*
* @REQUIRES:
* this.taxiStatus == IDLE;
* @MODIFIES:
* this.credit;
* @EFFECTS:
* this.credit = \old(this.credit) + 1;
* (\all PassengerRequest r in range, r.grabbedByTaxi(this))
*
*/
好
3. 没有规定范围
/**
*
* @REQUIRES:
* locX, locY, dstX, dstY;
* @MODIFIES:
* edge between (locX, locY),(dstX, dstY), ConsolePrinter;
* @EFFECTS:
* edge.existence == op;
*
*/
不好
/**
*
* @REQUIRES:
* 0 <= locX, locY, dstX, dstY <= 79;
* @MODIFIES:
* edge between (locX, locY),(dstX, dstY), ConsolePrinter;
* @EFFECTS:
* edge.existence == op;
*
*/
好
4. 遗漏了某些条件,一般是传入参数外的某些条件
/**
* @REQUIRES: mapVertex != null;
* @MODIFIES: ConsolePrinter
* @EFFECTS: \result == the opposite vertex of mapVertex
*/
不好
/**
* @REQUIRES: mapVertex != null && mapVertex.repOK == true;
* @MODIFIES: ConsolePrinter
* @EFFECTS: \result == the opposite vertex of mapVertex
*/
好
5. 对于一个容器中的所有对象,均需要规定前置条件
/**
*
* @REQUIRES:
* this.edgeMap != null
* @MODIFIES:
* None
* @EFFECTS:
* (\exist MapEdge e, edgeMap.contains(e), \min(edgeMap.flowrates) == e.flowrate && \result == e);
*
* @THREAD_EFFECTS:
* (\ all MapEdge e in this.edgeMap);
*/
不好
/**
*
* @REQUIRES:
* (\ all MapEdge e, this.edgeMap.contains ( e), e != null)
* @MODIFIES:
* None
* @EFFECTS:
* (\exist MapEdge e, edgeMap.contains(e), \min(edgeMap.flowrates) == e.flowrate && \result == e);
*
* @THREAD_EFFECTS:
* (\ all MapEdge e in this.edgeMap);
*/
好
后置条件
1. 不是布尔表达式
/**
*
* @REQUIRES:
* this.requestQueue != null
* @MODIFIES:
* None
* @EFFECTS:
* return this.requestQueue;
*
*/
不好
/**
*
* @REQUIRES:
* this.requestQueue != null
* @MODIFIES:
* None
* @EFFECTS:
* \result == this.requestQueue;
*
*/
好
2. 返回容器时不够明确
/**
*
* @REQUIRES:
* this != null
* @MODIFIES:
* None
* @EFFECTS:
* \result == (\all MapEdge e in this.edgeMap)
*
*/
不好
/**
*
* @REQUIRES:
* this != null
* @MODIFIES:
* None
* @EFFECTS:
* \result == new Arraylist<MapEdge> r;
* (\all MapEdge e, this.edgeMap.contains(e), r.contains(e))
*
*/
好
3. 改变值书写不规范
/**
*
* @REQUIRES:
* this != null, num > 0;
* @MODIFIES:
* this.credit;
* @EFFECTS:
* this.credit += num;
*
*/
不好
/**
*
* @REQUIRES:
* this != null, num > 0;
* @MODIFIES:
* this.credit;
* @EFFECTS:
* this.credit == \old(this.credit) + num;
*
*/
好
4. 没有写异常情况
/**
* @REQUIRES:
* this.list != null;
* @MODIFIES:
* None
* @EFFECTS:
* this.hasNext() ==> (\result == this.list[\old(index)+1] && index == \old(index) + 1);
*
* @THREAD_EFFECTS:
* \locked(this.list);
*/
不好
/**
* @REQUIRES:
* this.list != null;
* @MODIFIES:
* None
* @EFFECTS:
* this.hasNext() ==> (\result == this.list[\old(index)+1] && index == \old(index) + 1);
* exceptional_behavior(NoSuchElementException)
*
* @THREAD_EFFECTS:
* \locked(this.list);
*/
好
5. 后置条件没写全
/**
* @REQUIRES: key != null;
* passengerRequest != null;
* @MODIFIES: this.unprocessedRequests, ConsolePrinter;
* @EFFECTS: unprocessedRequests.contains(passengerRequest);
* @THREAD_EFFECTS: \locked(this.appendlock);
*/
不好
/**
* @REQUIRES: key != null;
* passengerRequest != null;
* @MODIFIES: this.unprocessedRequests, ConsolePrinter;
* @EFFECTS: unprocessedRequests.contains(passengerRequest); unprocessedRequests.size == \old(unprocessedRequest).size + 1
* @THREAD_EFFECTS: \locked(this.appendlock);
*/
好
四、功能Bug与规格Bug的聚类关系
本人仅在第九次作业中被报了功能bug,分别是输入格式错误会导致crash(说好的测试者保证呢)以及bfs在添加流量后判断条件有误导致找出了流量最小而不是距离最近的道路(在车聚集在一堆的时候可能绕路)。
之后的jsf问题我认为均是格式或者规范问题,与功能并没有什么关系,基本上都是功能实现正确但jsf写的时候可能有所遗漏。
五、撰写规格的思路与体会
之前写作业往往是先写程序代码最后再写规格,后来有尝试先写规格再改程序代码。规格的问题往往出在改正了程序的代码,然后程序跑着没什么问题了,结果改的地方一多就忘记改规格了。虽然看群里大家对于JSF的设计都有些抱怨,但JSF在复查代码的方面的确有一定的帮助,也对我形成工程化思想有了一些小小的推动作用。
希望课程组可以逐渐完善JSF,起码现在感觉很多复杂的逻辑用JSF表达起来非常费力以至于不得不用自然语言。
OO第三次阶段性总结的更多相关文章
- OO第三次课程总结分析
OO第三次课程总结分析 规格化设计发展历史 在网上找了好久也没找到合适的信息,稍稍参考了同学的博客.大致如下:最初的的软件并没有形式化方法,随着软件工程的兴起,为了便于工程间的协调管理,人们提出采用工 ...
- [BUAA OO]第三次博客作业
OO第三次博客作业 1. 规格化设计的发展 我认为,规格化设计主要源自于软件设计的两次危机.第一次是由于大量存在的goto语句,让当时被广泛应用的面向过程式的编程语言臃肿不堪,在逻辑性上与工程规模上鱼 ...
- OO第三次博客作业——规格
OO第三次博客作业——规格 一.调研结果: 规格的历史: 引自博文链接:http://blog.sina.com.cn/s/blog_473d5bba010001x9.html 传统科学的特点是发现世 ...
- OO第三单元作业总结
OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...
- 规格化设计——OO第三单元总结
规格化设计--OO第三单元总结 一.JML语言理论基础.应用工具链 1.1 JML语言 JML(java modeling language)是一种描述代码行为的语言,包括前置条件.副作用等等.J ...
- 【OO学习】OO第三单元作业总结
[OO学习]OO第三单元作业总结 第三单元,我们学习了JML语言,用来进行形式化设计.本单元包括三次作业,通过给定的JML来实行了一个对路径的管理系统,最后完成了一个地铁系统,来管理不同的线路,求得关 ...
- OO第三单元(地铁,JML)单元总结
OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...
- OO第三单元——基于JML的社交网络总结
OO第三单元--基于JML的社交网络总结 一.JML知识梳理 1)JML的语言基础以及基本语法 JML是用于java程序进行规格化设计的一种表示语言,是一种行为接口规格语言.其为严格的程序设计提供了一 ...
- OO第三单元作业——魔教规格
OO第三单元作业--魔教规格 JML的理论基础和相关工具 JML(Java Modeling Language,Java建模语言),在Java代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...
随机推荐
- javaweb基础 02--javaweb基础概念
1.WEB资源 * 静态web资源:指web页面中供人们浏览的数据始终是不变(如 html 页面). * 动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内 ...
- Python拷贝文件脚本
author : headsen chen date : 2018-12-06 17:56:58 copy_file.py #!/usr/bin/env python from sys import ...
- Build step 'Execute Windows batch command' marked build as failure
坑爹的Jenkis,在执行windows命令编译.NET项目的时候命令执行成功了,但是却还是报了这样一个错: Build step 'Execute Windows batch command' ma ...
- kvm/qemu虚拟机桥接网络创建与配置
首先阐述一下kvm与qemu的关系,kvm是修改过的qemu,而且使用了硬件支持的仿真,仿真速度比QEMU快. 配置kvm/qemu的网络有两种方法.其一,默认方式为用户模式网络(Usermode N ...
- 【BZOJ3691】游行 费用流
[BZOJ3691]游行 Description 每年春季,在某岛屿上都会举行游行活动.在这个岛屿上有N个城市,M条连接着城市的有向道路.你要安排英雄们的巡游.英雄从城市si出发,经过若干个城市,到城 ...
- Call removeView() on the child's parent first
extends:http://stackoverflow.com/questions/6526874/call-removeview-on-the-childs-parent-first Except ...
- Html5游戏框架createJs组件--EaselJS(一)
现在html5小游戏越来越火爆了,由于公司业务的需要,也开发过几款微信小游戏,用canvas写的没有利用什么框架,发现性能一直不怎么好,所以楼主就只能硬着头皮去学习比较火的Adobe公司出的Creat ...
- 集成maven和Spring boot的profile 专题
maven中配置profile节点: <project> .... <profiles> <profile> <!-- 生产环境 --> <id& ...
- ftok函数
ftok函数 系统建立IPC通讯(消息队列.信号量和共享内存)时必须指定一个ID值.通常情况下,该id值通过ftok函数得到. ftok原型 头文件: #include <sys/types.h ...
- wordpress---page页面数据调用
在wordpress的开发中,会使用wordpress的的页面,那么页面数据该怎么调用呢? 拿到页面的 content: <?php if(have_posts()) : ?> <? ...