私の経験では、言語サポートがなくても、契約による設計には価値があります。メソッドがオーバーライドされていないアサーションの場合、事前条件と事後条件の両方にドキュメント文字列があれば十分です。オーバーライドされるメソッドについては、メソッドを 2 つに分割します。事前条件と事後条件をチェックする public メソッドと、実装を提供し、サブクラスによってオーバーライドされる可能性のある保護されたメソッドです。後者の例を次に示します。
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()
ソフトウェア エンジニアリング ラジオのデザイン バイ コントラクトに関するエピソードから、デザイン バイ コントラクトの一般的な例として平方根を取得しました ( http://www.se-radio.net/2007/03/episode-51-契約による設計/ )。彼らはまた、アサーションはリスコフ置換原理を保証するのに役立たないため、言語サポートの必要性についても言及しましたが、上記の私の例はそうでないことを示すことを目的としています. C++ pimpl (プライベート実装) のイディオムもインスピレーションの源として言及する必要がありますが、それにはまったく別の目的があります。
私の仕事では、最近、この種のコントラクト チェックをより大きなクラス階層にリファクタリングしました (コントラクトは既に文書化されていましたが、体系的にテストされていませんでした)。既存の単体テストでは、コントラクトが複数回違反されていることが明らかになりました。私は、これはずっと前に行われるべきだったと結論付けることしかできません。また、契約による設計が適用されると、単体テストのカバレッジはさらに報われます。この手法の組み合わせを試す人は誰でも同じ観察をすることを期待しています。
ツールのサポートが改善されれば、将来さらに強力になる可能性があります。それは歓迎します。