契約プログラミングをやってみよう!
https://4.bp.blogspot.com/-brqkrQ7s7IA/VxC3SdJ169I/AAAAAAAA52M/Li1_oKQFQqEKcZtRugGBj1Ul89WfIUOEACLcB/s800/keiyaku_contract.png
契約プログラミングってなぁに?
本格的にやったことないので間違ってたら本当に申し訳ないと思う。
契約プログラミングは契約による設計とも呼ばれ "Design by Contracts" (DbC) と呼ばれることもある。 Eiffel というプログラミング言語で初めて導入され現在では D言語 でも利用可能な概念。 契約プログラミングを行う際は、コードの実装やコードの使用方法をドキュメントではなくコードとして取り込み、実装時における「契約」として機能させる。契約に違反するコードが実行された場合、例外として処理され実行が中断されるかあるいはコンパイル時にエラーになる。
契約プログラミングをサポートする言語ではコンパイル時に契約に関する実装自体が除去されるので実行時の効率に影響しないようになる。
契約の条件の種類
契約は、コードの利用条件が満たされることによって成立する。タイミングによって、以下の3種類のようなものがある。
事前条件 (precondition)
引数の型はもちろんだが、具体的に N以上 とか N以下、あるいはXを含む文字列みたいな条件をつけられる。
事後条件 (postcondition)
返り値が具体的にどんな内容であるかの条件をつけられる。
不変条件 (invariant)
コードが実行されている間、オブジェクトやクラスが持っている値の条件をつける。
コードを使う側が、事前条件と不変条件を満たすことで、呼ばれた側のコードは条件が常に満たされていることを前提にコードを書ける。逆に、コードを読んだ側は戻ってくる値が事後条件を必ず満たしていることを前提にコードを書けるメリットがそれぞれある。実行時点で契約の違反があれば例外として処理される。
雑には関数の入力値やオブジェクトのメンバーの値のバリデーションをものすごく手厚くした設計手法と考えることもできそうだ。何より間違いが発生するケースが減るのでテストコードをより限定的により強固に集中して書くようなこともできるようになる。そして先にも記載したように、値のバリデーションを行なっている実装はコンパイル時に除去される。
D言語での契約プログラミング
D言語は公式のドキュメントがしっかりしており、契約プログラミングをサポートしている手前、先の事前条件、事後条件、不変条件についてのサンプルもしっかり記載されている。概略としてはそちらを参考にするとイメージがつきやすいはずだ。