一、规格化设计调研
在《程序开发原理:抽象、规格与面向对象设计》一书中,提到了两种重要的程序语言的抽象方法:参数化抽象(abstraction by parameterization)和规格化抽象(abstraction by specification)。其中,关于规格化抽象,有如下的描述:
规格化抽象,是将执行细节(即模块如何实现)抽象为用户所需求的行为(即模块做什么)。这是从具体实现中抽象出模块,需要的仅仅是模块的实现能符合我们所依赖的表述形式。
当需要将某个过程与一个注释相关联时,使用规格化抽象是一个不错的选择。本书提及的是一种“Liskov风格”的规格设计方法,通常以成对的断言(assertion)注释出现:requires assertion(或称前置条件)和effects assertion(后置条件)。
而使用规格的一个理由在于过程调用的意义,通过如下两个严格的规则我们可以窥见规格抽象的好处:
- 在过程执行完毕后,可以认为后置条件中包含了当开始调用的时候前置条件成立所包含的内容。
- 我们仅仅认为那些从后置条件的出来的结论是成立的。
前一个规则使得用户不必关注具体实现的主体,后一个规则说明使得我们可以尽可能忽略不相干的信息。好的规格设计大大提高了抽象在程序设计中的作用,能够给开发者和设计者带来诸多的便利,更使得程序逻辑更加清晰,抽象出来的层次更加高级易懂。
二、规格BUG分析
前两次没有被找规格的bug,下面是最后一次被找的bug
类别 | 错误原因 | 被挂个数 | 备注 |
针对构造方法,初始状态repOK为真 | 没有写repOK | 2 | 无 |
Effects不完整 | 同步方法忘记写多线程的后置条件 | 3 | 同学找得很仔细 |
三、前置及后置条件改进例子
- 不好写法
- 过多使用自然语言
- effects写成具体实现过程
- 使用了中间变量
- 进行了同步控制却没有写相关的effects
- 格式不正确
- 改进措施
- 详细阅读JSF格式规范
- 学习其他JSF写得好的同学的代码
- 注意effects不关心开发者具体如何实现功能的
- 先写规格,再写方法体。先写规格,再写方法体
- 能使用数学语言描述就不要偷懒用自然语言代替
四、功能与规格BUG聚类分析
方法名 | 功能bug数 | 规格bug数 |
main | 1 | 2 |
readmap | 3 | 1 |
run | 0 | 2 |
五、设计与撰写规格的一些体会
这几次作业关于程序功能实现部分的代码量减少了,随之而来的是许多的规格书写。
其实并没有什么值得分享的规格设计与撰写的心得,因为和大部分一样写JSF时主要是为了能减少互测时被报规格bug,就只是做到了写得规矩,但绝对谈不上写得好,撑死了也只能算是差强人意吧。
体会倒是有。当面对一个复杂方法想了半天怎样用规范的数学语言书写规格,然而最后还是投降乖乖写自然语言的时候,觉得其实很多情况下,虽然自然语言显得不那么严谨,但确实在面对某些比较复杂的问题时,毋庸置疑它是比任何严谨的公式都要来得便捷易懂的交流工具。所以大概就像像荣老师说的吧,JSF这个东西说白了我们今后工作大概率不会使用到,更多的是使用自然语言撰写规格,但是,这个过程的训练可以使人的思维更缜密,更有逻辑性,会让之后使用自然语言写东西时逻辑更加顺畅,表达更加清楚,不会出现表意不清、歧义、不知所云的情况。