Abstract Data Type -ADT- and ObjectOriented Programming -OOP-
Designing Specification
一个完整的方法包括两个方面
- 方法的规约spec
- 方法的实现体implementation
- 代码本身就蕴含着你的设计决策,但是远远不够
- 代码中蕴含的“设计决策”:给编译器读
Specification
内容
What the method does, not how it does it
Interface (API), not implementation
- 前置条件:对客户端的约束,在使用方法时必须满足的条件
- 后置条件:对开发者的约束,方法结束时必须满足的条件
- 契约
- 如果前置条件满足了,后置条件必须满足
- 前置条件不满足,则方法可做任何事情
clauses | keyword |
---|---|
precondition | requires |
postcondition | effects |
parameter | @param |
results | @return @throws |
mutating methods 的 spec
在后置条件中声明所做的修改
除非在后置条件里声明过,否则方法内部不应该改变输入参数
程序员之间应达成的默契:除非spec必须如此,否则不应修改输入参数
spec中不应出现什么
A specification of a method can talk about the parameters and return value of the method, but it should never talk about local variables of the method or private fields of the method’s class.
Failing fast
When our precondition is violated, the client has a bug.
We can make that bug easier to find and fix by failing fast, even though
we are not obligated to do so.
using assert to fail fast
写出规约的原因
第一:自己记不住
第二:别人不懂
行为等价性
The notion of equivalence is in the eye of the client (站在客户端视角看行为等价性). 行为不同, 但对用户来说“是否等价”?
根据规约判断是否行为等价
若两个函数符合同一个规约,则它们等价。
优点
- 注释形式的“设计决策”:给自己和别人读
- 程序与客户端之间达成的一致,the implementer is responsible for meeting the contract, and a client that uses the method can rely on the contract
优点 - 精确的规约,有助于区分责任
- 客户端无需阅读调用函数的代码,只需理解spec即可
- 规约可以隔离“变化”,无需通知客户端
- 规约:扮演“防火墙”角色