擅长:python、mysql、java
<p>根据我的经验,合同设计是值得做的,即使没有语言支持。对于未重写断言的方法,连同docstring对于前置和后置条件都足够了。对于被重写的方法,我们将该方法分为两部分:一个检查前置和后置条件的公共方法,一个提供实现的受保护方法,并且可以由子类重写。下面是后者的一个例子:</p>
<pre><code>class Math:
def square_root(self, number)
"""
Calculate the square-root of C{number}
@precondition: C{number >= 0}
@postcondition: C{abs(result * result - number) < 0.01}
"""
assert number >= 0
result = self._square_root(number)
assert abs(result * result - number) < 0.01
return result
def _square_root(self, number):
"""
Abstract method for implementing L{square_root()}
"""
raise NotImplementedError()
</code></pre>
<p>我从软件工程广播(software engineering radio)上的一集“按合同设计”(design by contract)中得到了按合同设计(design by contract)的一般示例平方根。他们还提到了语言支持的必要性,因为断言在确保Liskov替换原则方面没有帮助,尽管我上面的例子旨在证明另一点。我还应该提到C++ PIPML(私有实现)习语作为灵感来源,尽管它有完全不同的目的。</p>
<p>在我的工作中,我最近将这种契约检查重构为一个更大的类层次结构(契约已经被记录,但没有系统地测试)。现有的单元测试显示,这些契约被多次违反。我只能得出这样的结论:这应该在很久以前就完成了,而且一旦按合同设计得到应用,单元测试覆盖率就会得到更大的回报。我希望任何尝试这种技术组合的人都能做出同样的观察。</p>
<p>更好的工具支持可能会在未来为我们提供更多的力量,我对此表示欢迎。</p>