1. 规格设计的发展历史

规格设计用于对程序设提供分解,抽象等的手段。在撰写代码规格的时候,需要对组成部件进行抽象。

在1960s,软件设计出现危机,例如Dijkstra提出了goto语句的种种危害,引发了软件开发领域长期的论战,并且在这时候产生了结构化程序设计方法,例如Pascal语言在1970s占据有统治地位。

之后,随着计算机软件规模日渐庞大,结构化程序设计方法开始无法满足用户的需求,面向对象程序设计(OOP)应运而生。面向对象程序设计是一场重大的革命,提高了开发人员的效率,有效的控制了软件开发的复杂度,提高了软件的可维护性和可拓展性。

规格化设计是随着面向对象程序设计的火热而发展起来的,可以有效提高程序的规范性以及程序的模块化划分。这样使得程序设计的数据更加安全,软件的可维护性得到有效的提高。

2. 规格Bug

由于我觉得JSF意义寥寥,没有认证对待,又或是我欧气不足,每次都被报了很多规格相关的bug

作业次数 Bug分类 具体原因
9 不符合JSF规范 JSF必须以/**开头,这个我没有注意
9 Modifies不完整 使用了较明显的自然语言
9 Requires不完整 前置条件必须为布尔表达式
10 Effects逻辑错误 \result == true了,不知道自己是怎么想的
10 Effects不完整 EFFECTS中的内容与Modifies重合
10 Requires逻辑错误 这个是因为修改了方法却忘了改规格,应该diff一下的
10 不符合JSF规范 Modifies应该只列出被修改的对象
11 Requires逻辑错误 Requires使用了自然语言
11 Effects不完整 Modifes中修改了this,但是没有在Effects中写出

3. Bug产生原因

  1. 第九次作业时,没有认真看JSF的说明,也很随意的使用了自然语言。
  2. 第十次作业时,首先这次作业出现了修改了代码但是忘记修改规格的问题,另外对Modifies和Effects的功能区别没有搞很清楚。
  3. 第十一次作业时,除了一点小错误,还是没有把Modifies和Effects的功能区别搞很清楚。

4. 不好写法举例

改进前:

/* @REQUIRES: None/* @
 * @MODIFIES: All that below... Sorry I won't copy it again :)
 * @EFFECTS: Call: gui.SetTaxiStatus()
 */

改进后:

/* @REQUIRES: None/* @
 * @MODIFIES: this
 * @EFFECTS: this != \old(this)
 */

改进前:

/* @REQUIRES: currentRequest is not null;
              state is ORDERED or SERVING;
              destination is not null;
              currentPoint is in roadMap.mapPoints[][];
 * @MODIFIES: state if destination is reached;
 *           currentPoint;
 *           gui
 * @EFFECTS: gui is updated
 */

改进后:

/* @REQUIRES: currentRequest != null;
              state == ORDERED || state == SERVING;
              destination != null;
 * @MODIFIES: state; currentPoint; gui
 * @EFFECTS: gui != \old(gui) && state != \old(state)
 */

改进前:

 private void finishRequest() {
    /**@REQUIRES: None
     * @MODIFIES: \this.currentRequest;
     *      \this.state;
     *      \this.destination;
     *      \this.startWaitingTime;
     * @EFFECTS: None
     */
  }

改进后:

 private void finishRequest() {
    /**@REQUIRES: None
     * @MODIFIES: this
     * @EFFECTS:  this != \old(this)
     */
    currentRequest = null;
    state = CarState.WAITING;
    destination = null;
    totalWaitingTime = 0;
  }

改进前:

synchronized private void moveRandom() throws InterruptedException {
    /**@REQUIRES: currentPoint in roadMap.mapPoints[][]
     * @MODIFIES: currentPoint;
     *            gui
     * @EFFECTS:  gui != \old(gui)
     */

改进后:

synchronized private void moveRandom() throws InterruptedException {
    /**@REQUIRES: \exist int r, c; 0 <= r < 80 && 0 <= c < 80 && RoadMap[r1][c1] == source &&
                   RoadMap[r2][c2] == destination;
     * @MODIFIES: currentPoint;
     *            gui
     * @EFFECTS:  gui != \old(gui)
     */

功能bug

第九次作业:

方法名 功能bug 规格bug
Car.update 1 0
CarsController.assignRequest 1 0

第十次作业:

方法名 功能bug 规格bug
RoadMap.addFlow 1 0

第十一作业:
| 方法名 | 功能bug | 规格bug |
| ---------------------------- | ------- | ------- |
| Car:update | 1 | 0 |

心得体会

要求用布尔语言来写规格实在有些不靠谱,毕竟做的不是数据结构题,很多函数用布尔表达式很难说清。如果真的想要完全说好,最后的规格可能比代码还要长。

收获大概是注释确实很重要,但还是表达清楚意思最为重要,不要拘泥与形式,当然这也可能是课程设计上为了互测做的不可避免的牺牲。

2018-北航-面向对象第三次OO作业分析与小结的更多相关文章

  1. 2018-北航-面向对象-前三次OO作业分析与小结

    基于度量的程序结构分析 由于平时使用了NetBrains出品的IDEA作为IDE,在分析程序的时候我使用了IDEA的插件Metrics Reloaded.然而在使用时发现不懂得很多分析项目的含义,因此 ...

  2. 【作业】HansBug的前三次OO作业分析与小结

    OO课程目前已经进行了三次的作业,容我在本文中做一点微小的工作. 第一次作业 第一次作业由于难度不大,所以笔者程序实际上写的也比较随意一些.(点击就送指导书~) 类图 程序的大致结构如下: 代码分析 ...

  3. 2018-北航-面向对象567次OO作业分析与小结

    设计策略及其变化 第五次作业-多线程电梯 在这次作业一开始的大部分时间,我一直想着怎样设计最为完美,完全使用BlockingQueue,导致交作业前发现设计并不能满足指导书的要求.最后仓皇之中加了一个 ...

  4. 【作业2.0】HansBug的5-7次OO作业分析与小结,以及一些个人体会

    不知不觉又做了三次作业,容我在本文胡言乱语几句2333. 第五次作业 第五次作业是前面的电梯作业的多线程版本,难度也有了一些提升.(点击就送指导书) 类图 程序的类图结构如下: UML时序图 程序的逻 ...

  5. 前三次OO作业总结

    一.作业总结 前三次的任务都是表达式求导.这是我在高中就思考过的问题,但是很久都没有付诸实践,直到学习了"类"这个强大的工具.还有正则表达式,如果能适当使用,则不失为一个字符串格式 ...

  6. 北航oo作业第一单元小结

    前言 在经过了三次艰辛的oo作业后,oo课程的第一单元告一段落,这一单元,我作为一个oo小白,开始了解oo的编程思想,也有了自己的一点心得体会.把笔粗成字,不当之处,还请各位大佬多多指教. 一.分析程 ...

  7. 前三次OO作业小结

    I used to be enamored of object-oriented programming. I'm now finding myself leaning toward believin ...

  8. 北航oo作业第二单元小结

    类的设计: 首先,我对我的思路进行整体的说明,由于我的三次作业,思路是继承的,所以做总体的说明 第一,   Main类,Main类自身并没有功能,他的功能只是构造需要的电梯线程和输入线程. 其中,第三 ...

  9. CS231n 2016 通关 第三章-SVM 作业分析

    作业内容,完成作业便可熟悉如下内容: cell 1  设置绘图默认参数 # Run some setup code for this notebook. import random import nu ...

随机推荐

  1. Where is HttpContent.ReadAsAsync?

    It looks like it is an extension method (in System.Net.Http.Formatting): HttpContentExtensions Class ...

  2. CodeForces 1105E

    题目链接 std:meet in the middle 首先把所有的点分成两部分,设\(f_i\)为前半部分在点集\(i\)中选出的最大独立集,\(g\)为在后半部分选.这个可以在\(O(2^{m/2 ...

  3. Unity3D学习笔记(十五):寻路系统

    动画生硬切换:animation.play();//极少使用,常用融合方法 动画融合淡入:animation.CrossFade(“Idle”, 0.2f);//0.2f为与前一动画的融合百分比为20 ...

  4. StringUtils类常用的方法讲解

    StringUtils 方法的操作对象是 Java.lang.String 类型的对象,是 JDK 提供的 String 类型操作方法的补充,并且是 null 安全的(即如果输入参数 String 为 ...

  5. 【Cuda编程】加法归约

    目录 cuda编程并行归约 AtomicAdd调用出错 gpu cpu下时间计算 加法的归约 矩阵乘法 矩阵转置 统计数目 平方和求和 分块处理 线程相邻 多block计算 cuda编程并行归约 At ...

  6. codeforces 251 div2 D. Devu and his Brother 三分

    D. Devu and his Brother time limit per test 1 second memory limit per test 256 megabytes input stand ...

  7. ros 安装c++编译的可执行文件

    xxx为c++源文件名 install( TARGETS xxx ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTI ...

  8. 理解Fragment的生命周期

    与活动类似,Fragment也有自己的生命周期.理解Fragment的生命周期有助于在Fragment销毁时能恰当地保存其实例,然后在重新创建时能够将其恢复至之前的状态. 下面的“试一试”将研究Fra ...

  9. [Android教程] Cordova开发App入门(二)使用热更新插件

    前言 不知各位遇没遇到过,刚刚发布的应用,突然发现了一个隐藏极深的“碧油鸡(BUG)”,肿么办!肿么办!肿么办!如果被老板发现,一定会让程序员哥哥去“吃鸡”.但是想要修复这个“碧油鸡”,就必须要重新打 ...

  10. LeetCode--035--搜索插入位置

    问题描述: 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 方法1:for 循环 class S ...