Software Construction——规约是啥?规约咋写?

写在前面

在说规约之前,我们先快速过一遍这两个东西:方法说明文档

1.方法是啥?
方法(method)由规约(specification)以及实现体(implementation)两部分组成的,它可以看作我们学c时写的函数。(规约是我们后面会提到,它调用方法的人可以看到的说明,实现体就是函数体)。它被视为程序的“积木”,可以被单独的开发测试和应用,调用者无需了解其内部如何实现,仅仅需要了解其功能以及限制。实际上可以看作我们学c时写的函数

2.那说明文档(document)呢?
它用来记述我们对程序的设计思想以及设计的限制与要求。对程序的设计往往需要用document记录下来,比如对方法输入的假设等。为什么?写下来这些假设既是因为自己经常记不住(真实),也是为了让别人(客户、优化)能够理解
当然,代码中往往已经蕴含了一部分设计决策,这些设计决策是给编译器读的,而你手写注释的那些设计决策,则是给人读的。

好了,现在我们步入正题。

关于规约

规约(或称为契约):明确双方的责任,定义正确实现的含义。(规约的内容)。我们写规约,既是为了分派任务,也为了实现后能够确认对错(写跑偏了就很糟糕)
它包含了:方法的输入、输出类型,功能, 性能(比如有时候我们会被要求写一些满足一定时间复杂度要求的方法)。
举个例子:
Software Construction——规约是啥?规约咋写?
它可以被看作一面防火墙,隔离供需双方。实现方法的人可以*改变实现方法,同时也不需要确保输入的正确性(保证输入正确是调用者的责任),因此可以提高我们的效率。

如何评价一个规约的质量?

我们有如下的标准:
1.规约的确定性:你有没有把功能、要求说清楚。
2.规约的陈述性:你是直接把实现思路扔上去了(这是极不好的行为,相当于对外暴露了信息)还是陈述出了它的功能与要求。
3.规约强度:你对输入的要求严不严格(比如是不是可以传一个父类参数进去而非必须要求某个子类的参数)?你对输出结果的要求严不严格(比如有两个正确结果,你是不是还非得要求我必须给你最小的那一个)?
(有同学想问,为什么要比较规约?因为有时我们想要判断是否能用一个规约来替换另一个。)

如何设计出一个好的规约?

方法很简单:易于阅读、双方(写方法和用方法的人)都用着舒服。

什么意思?

1.规约描述的功能应该单一、简单,易于理解(别老一个方法里实现好几个功能,多繁杂呀)。
2.信息要给足,双方理解一致(就是把话说清楚)。
3.规约强度要适宜,太强了(结果要求太严格)你开发着不爽,太弱了(输入要求太严格)客户不爽。
4.尽量使用抽象类型(List、Map什么的,这是方法签名里体现的),给你实现的更大*空间。
5.另外,是否应该在里面写一些前置条件?
写了的话,前置条件太强,客户不喜欢;如果不写,需要在方法内部去check是否满足条件,但是这样你的实现代价可能很大。事实上,写不写前置条件一定程度上取决于这个代价大不大,还是较为主观。另外,如果只是在类的内部使用该方法,可以不写前置条件,在调用方法的各个位置check一下就行;如果是public的方法,还是写个前置条件为好。

写在最后

规约是软件设计过程中很重要的一部分财产:它能帮助我们更好的铭记我们想要去实现一个什么样的产品,也能更好的让用户知道方法的功能,从而从两个方面减少bug的产生;另外,简洁的规约让我们的程序更容易理解,更容易复用。因此,学习了解规约的设计会让我们在今后的程序设计过程更加清晰方便。