一般的な契約プログラミングについてはWikipediaに記載がありますが、簡単に言うと、クライアント(メソッドのユーザ)とサプライヤー(メソッドの提供者)がそれぞれ守るべきことを定めるというものです。
あるメソッドを呼び出すときに、クライアント側は事前条件に定められたことを守り、サプライヤー側は事前条件が満たされているときに不変条件・事後条件が満たされていることを保証をします。
この方式を「具体的にJavaで実装するとこうなる」というものをまとめてみました。
1. 取りうる選択肢
一般的なJavaのコードで記載する場合は、以下2つの方法を使い分ける必要があります。
a. 明示的に値チェックを行う(エラーの場合例外を投げる)もの
- public メソッドの事前条件(precondition)
b. assertによる値チェックを行うもの
- private メソッドの事前条件(precondition)
- 不変条件(invariant)
- 事後条件(postcondition)
ただし、この方法で実装すると「実現したいこと」を行う部分に加えて大量のコードを記載する必要があり、可読性も落ちてしまいます。
この問題に対応すべく、Javaで契約プログラミングを実現するためのライブラリが作成されています。
Cofoja Googleが作成したオープンソースのライブラリ
ModernJass フリーのライブラリ
いずれもアノテーションを利用して契約プログラミングの条件チェックを行うようになっています。
アノテーション名はわかりやすく、可読性は高いと言えますが、コーディングする際には書き方を覚える必要が有ります。そのため、簡単にプロジェクトに導入することはできなさそうです。
2.結論
以下のいずれかからプロジェクトの特性に応じて方式を選択するしかなさそうです。
a. 契約部分はドキュメントorコメントに残すor全く記載せず、public メソッドの事前条件のみ違反時に例外を投げる
明らかな用法誤りはチェックし、それ以外はコードとしては記載しない。
メリット
一番軽い案で、工数は掛からない。ユニットテストで事後条件・不変条件をテストすれば、最低限目的は果たせる。
デメリット
ユニットテストで確認できる範囲でしか、事前条件以外が守られていることを機械的に確認することができない。
契約の記載方法が人によって異なる。
b. 契約を記載するためのライブラリを利用する
1.で紹介したようなライブラリを利用することで契約を記載する。
メリット
契約が守られていることを機械的に確認することが出来る。
契約について、統一的な記載をすることができる。
デメリット
導入時に教育コストが掛かる。
プロジェクトが依存するツールが増える。
メジャーなツールがない?
個人でプロジェクトを進めていく分には、a.でいいかと思います。
中・大規模開発時には、b.の方法を取る方が統一的な記載ができますが、一方でどのツールを採用するか等考えなければいけないことが増えてしまいます。
a.案を取りつつコーディング規約で統一感を出すのも良さそうですが、その制定や周知、守られているかのチェック等手間も増えてしまいます。
一番いいのはわかりやすく実装できるプログラマを集めることでしょうか。。