契約による設計~あなたのモジュールが守るべき約束とは

design-by-contract
契約による設計

Design by Contract (DbC)

事前条件、事後条件、不変条件、を契約せよ

プログラム設計の安全性を高めるための設計手法です。

目次

DbCの3つの契約~事前条件、事後条件、不変条件

あなたのクラス/メソッドは、それを使う人に対し、以下の3つの契約を交わします。

  • 事前条件 メソッド開始時に、呼ぶ側が保証すること
  • 事後条件 メソッド終了時に、呼ばれた側が保証すること
  • 不変条件 メソッド開始時および終了時に、オブジェクトが保証すべきこと

事前条件 (precondition)

メソッドを呼び出すときの入力値には、この範囲の値しか受け付けられない、この文字は空であってはいけない、など条件付きとなる場合があります。

例えば「平方根を求める」メソッドなら、その入力は0以上でなければなりません。(そうでないと計算できない)

メソッドを呼び出す側は、メソッドが正常動作する入力を与えるこれが事前条件です。

事後条件 (postcondition)

事前条件が満たされると、メソッドが実行され、結果が返却されます。その結果は呼び出し元の求めるものとなっている必要があります。

「平方根を求める」メソッドなら、input=result*result となっていることが、求める結果です。

メソッド側は、メソッドを呼び出した側に期待する出力を返却するこれが事後条件です。

不変表明 (invariant)

メソッドを呼ぶ前も呼び出した後も、クラスがその外部に公開しているすべての操作について、開始時と終了時に保証されるべき性質です。

例えば、balance == sum(entries.amount()) といった条件は、いつでも成立している必要があります。

クラスは、公開するすべての操作について常に約束された状態を守るこれが不変表明です。

表明(assert)による契約の確認

契約を結んだら、その契約が守られているかを確認する必要があります。

契約による設計での、確認の基本は「表明」(assertion)です。

表明とは

表明とは、必ずfalseにならない真偽式です。例えば「平方根を求める」メソッドなら

平方根を求めるメソッドの表明
  • 事前条件の表明 input ≧ 0
  • 事後条件の表明  input=result*result

となります。

表明が false となったとき、それは契約違反があることを示します。

assertによる表明の実装

C,C++,C#,Java,Pythonなど、多くのプログラム言語では、assert と呼ばれる機構が備わっています。

assert input = result * result

ほとんどの場合、assertは、false となった時点で即時にプログラムが停止します。false、つまり契約違反となるのはバグであり、回復不可能だからです。

このことからも分かるように、assertはバグを検出するためのものです。

通常発生しうる状態(バグでない状態)に、表明(assert)を使ってはいけません。

assertは、どのプログラミング言語でも「リリーズ時は無効とする」オプションが備わっています。

契約による設計の利点

クラスの頑健性があがる

契約による設計は、「クラス内部で何をするか」ではなく、「クラス外部に何を約束するか」に着目します。

結果、そのクラスが持つべき責任が明確となります。外部からの使い方も明確になり、不具合の少ない頑健なクラスができます。

テストによる品質確認が容易

契約による設計によって設計されたクラスは、ユニットテストによる品質確認も容易となります。

そう「契約が守られているか」を確認すればよいのですから。テストケースも明確になります。

テスト駆動開発との相性は抜群です。【テスト駆動開発】TDDの実践方法と、メリットと注意事項

まとめ

クラス設計時にはついつい、その中身をどうするか、に心を奪われてしまいがちです。

そうすると、使う側にとってはいまいち使いにくいクラスができあがります。

「契約による設計」を使うと、クラスを使う側の視点に立った設計ができます。あなたのクラスを強固なものにしましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次