契约模式Design by Contract
契约模式Design by Contract
背景
Design by Contract是Bertrand Meyer总结的一项设计技巧,也是Meyer发明的Eiffel语言的主要特点。不过,这条原则的作用范围并不局限于Eiffel,而是所有的程序设计语言。
那么什么是Contract呢?
我们在声明一个函数/方法的时候,对函数的输入和输出所具备的性质是有所期望和规定的。有时候这种性质会被我们明确的写出来,有时候会被我们忽略掉。这些期望和规定就是Contract。
核心
核心是断言(assertion)。所谓“断言”,是指永远为真的布尔型语句,如果不为真,则程序必然存在错误。通常情况下,检查断言的时机,应该局限于调试(debug)阶段,而不是代码的实际执行阶段。实际上,完成的程序永远不应期望断言会被检查。
Design by Contract使用了三类断言:post-conditions,pre-condition,以及invariants。违反这些操作会导致程序抛出异常
post-conditions,是指操作执行完之后的情况,发生在每个操作的最后
pre-condition,是指在执行操作之前,期望具备的环境,发生在每个操作(方法,或者函数)的最开始。
invariants,是指使关于类(class)的断言,实际上是前置条件和后置条件的交集。
歪理
从核心来看,这意味着,不变量可以应用于特定类暴露的所有公开操作的前提条件与后继条件。在方法的执行过程中,不变量可能为假,但是,在其他任何对象能够与被调用方进行交互的时刻,不变量断言必须恢复为真。
在继承关系中,断言扮演着独特的角色。继承的风险之一在于,开发人员为子类重新定义的行为,可能会违背父类的行为。断言减少了这种风险。对某个类来说,其不变量和后继条件必须能够应用于所有的子类。子类可以加强这两类断言,增加更多的限制,而不能削弱它们。而前提条件则只能削弱,而不能增强。
可能有些隐晦难懂可以看这里