规约设计 Designing Specification

在最近写程序的时候,老师强调了写程序一定要写spec,涉及到了spec的设计书写,起初还难以接受,但在完成实验二特别是P3部分的时候,以小见大逐渐体会到了spec的重要性。(毕竟没有规约的代码都是trash,开个玩笑)

规约的说明

首先我们需要知道什么是规约(specification)。从代码角度来说,规约相当于一个说明,读你的规约,我们就可以知道你的代码想要完成什么功能,你的传入参数,你的返回值,你的异常处理等等,但是并不包括你的内部实现,它仅仅是一个说明。从客户端和书写ADT的程序员之间来说,这也相当于一种契约,在spec规定说明的情况下,对于每一种情况程序应该做出什么样的处理都是固定的。如果客户违反了spec,那么不客气的说程序就可以为所欲为了(有良心的程序员当然不会为所欲为的)。spec就是客户端和程序员之间的合同,双方都需要满足spec里面的要求,都需要履行相应的责任。

为什么要写规约

简言之,再次引用老师的话,没有spec的方法都是垃圾。
没有规约,就相当于没有目标,没有明确你的程序要做出什么,那么这样的话就会引出下一个问题,即使写出了程序,也无法判断程序的正确性。
比如说,我们自己写了一个方法,我们自己是知道他的用途和处理情况的,但是你的同学或者同事是不知道你这个方法的用途的。即使你的变量名和方法名写的相当明白,我们也不应该只靠用户通过我们的命名去猜一个方法的参数返回值以及作用。更何况,在很多设计情况下,你的代码是不想让别人看到的,有很多的bug都出在程序员和客户端之间的误解。例如我编写的程序不希望客户输入一些不合法的数据,但是没有specification,客户并不知道那些事不合法数据,就会导致程序出错或者得到非法的结果。我们要做到不让客户端阅读你的代码就知道如何用你的代码。
又如,在团队合作中,一个大型程序设计过程中需要多人协作,那么如果在你的程序中的所有方法都是只有命名的形式没有spec存在的话,对于与你协作的同事来说如何理解你的方法声明和用途就是一件难以预料的事,也不用说如何保证调用的正确性了。
最后为了不给自己找麻烦,我们也应该且必须写spec,为了避免一个bug找一天这种痛苦经历,写出spec能帮助我们更快的定位错误,少写一些bug出来。避免bug这个问题,还应该引入测试优先的编程思想,先写出测试文件,再开始写代码。
所以说specification对于一个好的程序是必不可少的,而且往往程序对specification的要求很高。

如何写好一个规约

spec需要明确输入、输出的数据类型,需要讲清楚方法的功能以及它的正确性,异常处理情况,以及它的Performance expectations(性能)。

前置条件

前置条件(Preconditions)是对客户端的约束,说明了客户端在使用方法时必须满足的条件,规定了用户输入的参数的有效范围,规定方法调用必须满足的条件,一旦出现不合法的输入情况,如果没有明确规定处理方法的时候,这个时候也就无法保证程序的正确性了。

后置条件

后置条件(Postconditions)是针对程序设计开发人员,规定方法调用结束必须满足的条件。例如,返回值的范围.
前面提到的契约就是一旦前置条件满足,后置条件也必须满足!

异常行为处理

异常行为是针对用户的异常行为的处理方法,一旦用户输入违反了前置条件,异常行为就是规定发生的一些异常的处理方式,是一种对程序设计方式的规定,也是一种约定,要求我们必须遵守的。未说明的情况下可以随意处理,但这样极不合理。

注释

注释由如下部分组成
1、方法的目的,是用来做什么的
2、@param:输入的参数
3、@return:方法的返回值
4、@throws:这个方法中可能抛出的异常(checked and unchecked)
5、thread safety issues:线程安全的策略。
注意:方法没有涉及的部分,则不需要写,例如void没有return,某些方法无需传入参数等等。
根据一个标准的注释则可以生产java doc文件,一个十分自动化的过程,极大的提高了我们的编程效率。

一个java的注释示例。

规约设计注意事项

1:spec必须是确定的
一个好的spec要考虑到每一种输入情况,对于每一种的输入都有相应的处理,也就是对策方案。
2:spec的强度要适中
那么就引入了下一个问题,如何判断spec的强度呢,或者说如何比较两个规约?
在前置条件相同的情况,后置条件强的规约更强。在后置条件相同的情况下,前置条件更弱的规约更强。所以spec变强:更放松的前置条件+更严格的后置条件。
由于spec的前置条件是对客户端的约束,那么很容易判断输入情况,当后置条件一定时,客户的输入范围更大,输入更宽松对客户的体验来说更好;同样当前置条件一定时,后置条件更明细,更确定时,用户的体验最好,但是这也给程序员的编程带来了更大的难度,需要消耗更多的时间。
太弱的spec,明确性不高,甚至输出不明确,体验很差;而太强的spec,需要程序员付出的辛苦更多,更耗费精力。因此这就需要我们程序员在设定spec的时候在强度上做一个折中,找到一个完美的平衡点。
3:spec必须是清晰的
方法设计的spec不能模棱两可,不能给客户带来歧义。例如,在表达返回值为某一个数值时,我们一定要讲更清楚在什么情况下返回它,一共对应几种情况。
4:在规约中使用抽象类型
采用抽象数据类型可以给方法的实现体与客户端更大的自由度。并且在这里推荐设计ADT时采用接口这一结构,将具体的实现类单独写出来,在方法的设计类不要写具体的实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值