契約による設計はあなたにとってうまくいきますか?[閉まっている]

StackOverflow https://stackoverflow.com/questions/26455

  •  09-06-2019
  •  | 
  •  

質問

専門的に契約による設計を使用していますか?それはプロジェクトの最初からやらなければならないことなのでしょうか、それともギアを変えてソフトウェア開発ライフサイクルに組み込むことができるのでしょうか?この設計アプローチの長所と短所は何だと思いますか?

私が出会ったのは、 契約による設計 大学院コースでのアプローチ。学術的な場面では、これはかなり有用なテクニックであると思われました。しかし、私は現在、Design by Contract を専門的に使用していません。また、これを使用している他の開発者を知りません。SO 群衆から実際の使用法について聞くのは良いことです。

役に立ちましたか?

解決

あまりお勧めできません。次のように、インラインのドキュメント契約仕様を受け入れるスイートがある場合は特に便利です。

// @returns null iff x = 0
public foo(int x) {
  ...
}

そして、次のようにそれらを生成された単体テストに変換します。

public test_foo_returns_null_iff_x_equals_0() {
  assertNull foo(0);
}

こうすることで、実行しているテストを実際に確認できますが、テストは自動生成されます。ちなみに、生成されたテストはソース管理にチェックインすべきではありません。

他のヒント

相互に通信する必要があるアプリケーション間のインターフェイスがある場合、契約による設計の真の価値がわかります。

契約がなければ、この状況はすぐに責任の所在を問うテニスのゲームになってしまいます。チームは何度も非難を繰り返し、膨大な時間が無駄になります。

契約があれば、責任は明らかです。

呼び出し元は前提条件を満たしていましたか?そうでない場合は、クライアント チームが修正する必要があります。

有効なリクエストが与えられた場合、受信者は事後条件を満たしましたか?そうでない場合は、サーバーチームがそれを修正する必要があります。

両当事者は契約を遵守しましたが、結果は満足のいくものではありませんか?契約が不十分であるため、問題をエスカレーションする必要があります。

このためには、契約をアサーションの形式で実装する必要はなく、契約が文書化され、すべての当事者によって合意されていることを確認するだけで済みます。

STL、boost、MFC、ATL、および多くのオープン ソース プロジェクトを調べてみると、非常に多くの ASSERTION ステートメントが存在し、プロジェクトをより安全に進めることができることがわかります。

契約による設計!実際の製品でも実際に機能します。

フランク・クルーガー 書きます:

ガイウス:Null Pointer 例外はランタイムによって自動的にスローされるため、関数プロローグでそのようなものをテストするメリットはありません。

これに対する私の返答は 2 つあります。

  1. Null はほんの一例です。square(x) の場合、結果の平方根が (おおよそ) パラメーターの値であることをテストしたいと思います。セッターの場合は、値が実際に変更されたかどうかをテストしたいと思います。アトミック操作の場合、すべてのコンポーネント操作が成功したか、すべて失敗したかを確認したいと思います (実際には、成功の場合は 1 つのテスト、失敗の場合は n 回のテスト)。弱い型指定言語のファクトリ メソッドの場合、正しい種類のオブジェクトが返されるかどうかを確認したいと思います。リストはまだまだ続きます。基本的に、1 行のコードでテストできるものはすべて、プロローグ コメントのコード コントラクトの非常に良い候補になります。

  2. 実行時例外が発生するからといってテストすべきではないという意見には私は同意しません。どちらかといえば、あなたは すべき 実行時例外を生成する可能性のあるものをテストします。私は実行時例外が好きです。 早く失敗する, 、デバッグに役立ちます。しかし null この例では、考えられる入力に対する結果値が示されています。二度と戻らないことには議論の余地がある null, しかし、やるならテストしてみるといいでしょう。

SOA 領域で何かを行うときに契約に基づいて設計しないのは絶対に愚かです。特にブラック ボックスが関係する場合、後から部分と部分が交換される可能性があるあらゆる種類のモジュラー作業に取り組んでいる場合には、常に役に立ちます。 。

より表現力豊かなタイプシステムの代わりに、私は軍用レベルのプロジェクトでは絶対に契約によるデザインを使用します。

弱く型付けされた言語または動的スコープを持つ言語 (PHP、JavaScript) の場合、関数コントラクトも非常に便利です。

それ以外のことについては、ベータ テスターや単体テストに依存することは捨てます。

ガイウス:Null Pointer 例外はランタイムによって自動的にスローされるため、関数プロローグでそのようなものをテストするメリットはありません。ドキュメントにもっと興味がある場合は、静的アナライザーなどで使用できるアノテーションを使用します (たとえば、コードがアノテーションを破壊していないことを確認するため)。

Design by Contract と組み合わせた、より強力な型システムが進むべき道のようです。を見てみましょう 仕様番号 たとえば:

Spec# プログラミング言語。Spec#は、オブジェクト指向言語C#の拡張機能です。タイプシステムを拡張して、非ヌルタイプとチェックされた例外を含めます。オブジェクトの不変と同様に、事前条件と事後条件の形でメソッド契約を提供します。

私の経験では、単体テストと契約による設計はどちらも貴重なテスト アプローチです。

私はシステム自動テストフレームワークで契約による設計を使用してみましたが、単体テストでは簡単に得られない柔軟性と可能性が得られるというのが私の経験です。たとえば、より長いシーケンスを実行し、アクションが実行されるたびに応答時間が制限内であることを確認することが可能です。

InfoQ のプレゼンテーションを見ると、契約による設計は、コンポーネントの統合フェーズにおける従来の単体テストへの貴重な追加であるようです。たとえば、最初に模擬インターフェイスを作成し、次にコンポーネントを使用して、コンポーネントの新しいバージョンがリリースされたときに使用することができます。

.NET/Microsoftプラットフォームでの契約テストで設計するためのすべての設計要件をカバーするツールキットは見つかりませんでした。

私は実際に、Design by Contract を日常的に使用しているわけではありません。ただし、それが組み込まれていることは知っています。 D 言語の一部としての言語。

はい、そうです!実は数年前、私は引数検証のための小さなフレームワークを設計しました。私は、別のバックエンド システムがあらゆる種類の検証とチェックを行う SOA プロジェクトを行っていました。しかし、応答時間を増やすため (入力が無効だった場合、およびバックエンド システムへの負荷を減らすため)、提供されるサービスの入力パラメーターの検証を開始しました。Not Null だけでなく、String パターンにも対応します。またはセット内の値。また、パラメータ間に依存関係がある場合も同様です。

今、私たちは当時、契約フレームワークによる小さな設計を実装していたことに気づきました:)

ちょっとしたことに興味のある方はこちらのリンクをどうぞ Java 引数の検証 フレームワーク。これはプレーンな Java ソリューションとして実装されています。

Go プログラミング言語には、契約による設計を可能にする構造が存在しないことがわかります。遅延と回復のロジックによりパニックを無視し、IOW で違反したコントラクトを無視できるため、パニック/遅延/回復は正確には異なります。少なくとも必要なのは、ある種の回復不能なパニックであり、それはまさにアサートです。あるいは、せいぜい、契約構造 (事前条件と事後条件、実装およびクラスの不変条件) による設計の直接言語サポートです。しかし、囲碁船の舵取りをしている言語純粋主義者の頑固さを考えると、私はこれまでに行われたことにはほとんど変更を加えません。

パニック関数の最後の遅延関数で特殊なアサート エラーをチェックし、リカバリ中に runtime.Breakpoint() を呼び出してスタックをダンプすることで、アサートのような動作を実装できます。アサートのように動作するには、条件付きである必要があります。もちろん、このアプローチは、assert を実行する関数の後に新しい遅延関数が追加されると破綻します。大規模なプロジェクトではこれがまさに間違ったタイミングで起こり、バグが見逃されることになります。

私が言いたいのは、assert は非常に多くの点で役立つため、それを使いこなすのは頭の痛いことかもしれないということです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top