怎样写好一个Java的Specification(of a method)

一、为什么要写Specification(规约)

  首先Specification是团队合作的关键。如果没有规约就没办法写出程序,即使写出了程序也无法判断程序的正确性。其次,specification也是程序和客户端之间达成的一致,即客户端的要求是什么,我们程序员需要做什么等等。specification不仅给我们程序确定了责任(我们需要编写怎样的程序),也同样给客户端确定了责任(他们需要遵守怎样的输入原则,输入怎么样的数据等等)。

  如果不写specification会有什么样的后果?

  也许会引入很多不必要的bug,就比如:我编写的程序不希望客户输入一些不合法的数据,但是没有specification,客户并不知道那些事不合法数据,就会导致程序出错或者得到非法的结果。而且没有specification,和你一起编写程序的伙伴,可能和你产生不同的理解导致开发的不同的部分是不兼容的。没有规约我们也很难定位程序的错误。

  所以说specification对于一个好的程序是必不可少的,而且往往程序对specification的要求很高。

二、怎样写Specification

  specification需要明确输入、输出的数据类型,需要讲清楚method的功能以及它的正确性,以及它的Performance expectations(性能)。

1、Specification structure : pre-condition and post-condition(前置条件和后置条件)

前置条件通过“requires”描述,前置条件是对客户端的约束,在使用方法是必须满足的条件。

后置条件通过“effects”描述,后置条件是对开发者的约束,方法结束时必须满足的条件。

1、如果前置条件满足,则后置条件必须满足。

怎样写好一个Java的Specification(of a method)

2、如果前置条件不满足,则方法可做任何事情

怎样写好一个Java的Specification(of a method)

所以客户端只有在满足前置条件的情况下输入正确的数据,才能得到他们想要的结果,有了spec可以减轻开发者的负担,排出一些非法的情况。

除非在后置条件中声明过,否则内部方法不应该改变输入参数。开发者应该尽量遵循这个规则。尽量避免使用可变的数据类型。

2、Document(注释)

1、方法的目的,是用来做什么的

2、@param:输入的参数

3、@return:方法的返回值

4、@throws:这个方法中可能抛出的异常(checked and unchecked)

5、thread safety issues:线程安全的策略。

3、Specification的强弱判断

如何比较两个规约?

在前置条件相同的情况,后置条件强的规约更强。在后置条件相同的情况下,前置条件更弱的规约更强。

所以spec变强:更放松的前置条件+更严格的后置条件。

怎样写好一个Java的Specification(of a method)

规约越强说明对开发者的要求越高,对客户端的约束越小。所以过分的追求高强度的规约会大大较重开发者的任务。

三、Quality of a specificaton(规约的质量指标)

1、规约应该是内聚的:spec描述的功能应该单一、简单、易理解

2、规约应该是信息丰富的:例如,在表达返回值为null时可以讲的更清楚在什么情况下返回null。不过在信息丰富的同时不能让客户机产生理解的歧义。

3、规约需要一定的强度。即后置条件需要强一些,前置条件需要弱一些。通俗的来讲就是不要限制客户太多,尽可能满足客户的所有需求。

4、在规约中使用抽象类型,可以给方法的实现体与客户端更大的*度。

5、可以减少前置条件,在方法中检测输入的参数如果不合法可以抛出异常。(需要考量检测合法数据的代价)。