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代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...
随机推荐
- 第二步 (仅供参考) sencha touch + PhoneGap(cordova 2.9 及其以下版本) 使用 adt eclipse进行打包
首先你得安装一个adt-eclipse 参考资料 http://www.crifan.com/android_eclipse_offline_install_adt/ 然后就可以运行adt-eclip ...
- 学习生活必须知道的网站或者App
转载自:https://www.douban.com/group/topic/89798480/ 学习方面: 1.网易公开课(http://v.163.com/special/test/alltest ...
- 深入浅出WPF之Binding的使用(二)
在上一篇中介绍了Binding的基本绑定方法,这一篇中我们在深入的介绍Binding的其他用法. Binding的源也就是数据的源头,在日常的工作中,除了使用像上一篇中的Student对象作为数据源外 ...
- 【BZOJ4355】Play with sequence 线段树
[BZOJ4355]Play with sequence Description 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a ...
- Unity3D之游戏架构脚本该如何来写
这篇文章主要想大家说明一下我在Unity3D游戏开发中是如何写游戏脚本的,对于Unity3D这套游戏引擎来说入门极快,可是要想做好却非常的难.这篇文章的目的是让哪些已经上手Unity3D游戏引擎的朋友 ...
- "will you marry me" vs "would you marry me"
will you marry me 表示我现在问你,能不能嫁给我,我现在就需要答案. 如果回答是yes,那么对方就算是同意嫁给你了. would you marry me 表示你能不能考虑嫁给我. w ...
- backbone.js之Model篇 简单总结和深入(2)
一.模型属性的一些操作方法 1.mmodel.get() 获取属性的值 2.mmodel.set('age',5) 更新单个属性的值 mmodel.set({name:'aaa',age:6}) ...
- Python开发环境搭建方法简述
先插入一条广告,博主新开了一家淘宝店,经营自己纯手工做的发饰,新店开业,只为信誉!需要的亲们可以光顾一下!谢谢大家的支持!店名: 小鱼尼莫手工饰品店经营: 发饰.头花.发夹.耳环等(手工制作)网店: ...
- python pandas 豆瓣电影 top250 数据分析
豆瓣电影top250数据分析 数据来源(豆瓣电影top250) 爬虫代码比较简单 数据较为真实,可以进行初步的数据分析 可以将前面的几篇文章中的介绍的数据预处理的方法进行实践 最后用matplotli ...
- 7.20python线程(2)
RLock 递归锁 线程事件