1

コード コントラクトについて詳しく学ぶと、自分のプロジェクトで使用したいもののように思えます。

Web サービス レイヤー (MVC コントローラーからアクセスされるサービス レイヤーの抽象化) を構築する方法を考えると、インターフェイス実装のさまざまな順列に対して異なるコントラクトを指定できないのはなぜだろうかと思います。

具体的には、ジェネリック インターフェイス メソッドが与えられた場合、コントラクトを 1 対 1 の方法でしか指定できない理由に興味があります。

これが私のコード構造の例です。コード コントラクトをどのように使用したいかを特定することを目指します。より多くの経験を持つ誰かが私を正しい方向に向けることができると確信しています.

私は次のような CQRS スタイルのアプローチを使用しています。

public interface IQuery<in TInput input,out TOutput output>
{
     TOutput Invoke(TInput request)
}

public interface IGetSomeUnicornsFromAMagicalLand : 
                                             IQuery<int, IEnumerable<Unicorn>>{}

 // Implementation
public class GetSomeUnicornsFromMagicLand : IGetSomeUnicornsFromAMagicalLand
{
    public IEnumerable<Unicorn> Invoke(int numberOfUnicornsToReturn)
    {
       // Here I'd like to specify some preconditions on the input, 
       // specific to type int

       return _wizardry
                 .GetMagicCreature<Unicorn>(numberOfUnicornsToReturn)
                 .DoMagicalConversionToEnumerable()
    }

}

このコンテキストを考えると、(一般化されたメカニズムとして) インターフェイスにコントラクトを適用するように設計された抽象クラスではなく、実装レベルでコントラクトを指定することが合理的であるように思われます。

  • これができない理由にはどのようなものがありますか?
  • これに対応する他のアプローチはありますか?
  • コード契約を使用したい場合、これは良い構造ではありませんか?
4

1 に答える 1

2

Liskov Substitution Principleに照らして、一般に、これらのコントラクトをインターフェイス レベルで指定する方が理にかなっていると思います。

LSP は基本的に、抽象概念の各実装は、抽象概念のユーザーが違いを知らなくても交換可能であるべきだと述べています。つまり、特定のインターフェイスの別の実装に切り替えることで、コードが壊れ始めることがあってはなりません。

入力引数に実装固有の追加要件を課すことにより、呼び出し元のコード (この場合、 の一般的な概念を扱うフレームワーク レベルのコードである可能性が最も高いIQuery) を特定の実装に効果的に結合します。

あなたの特定の状況では、推論が適用される場合と適用されない場合があります(それが原則であり、石で書かれていないのはそのためです)が、コード契約のような一般的なフレームワークは一般的な原則のみを考慮に入れることができます:-)

編集:これをもう少し考えた後、派生インターフェースはおそらく「本物の」インターフェースであり、ジェネリックではないようIQuery<TInput, TOutput>です。ジェネリック ベース インターフェイスは、「実装の詳細」に近いようです。実際、このジェネリック ベース インターフェイスで意味のある仮定 (契約) を作成することはできません。具体的なレベルでのみ、これらの入力パラメーターと出力パラメーターについて意味のある推論を行うことができます。

このインターフェースをコンシューマーから「隠す」ために、C# で C++ のプライベート継承 (または実装継承) が必要になる場合があります。関連する質問に対するこの優れた回答を読んでください。また、この場合、Liskov Substitutability は「嘘」であると述べており、私はこれに同意する傾向があります。

于 2012-07-25T08:48:29.853 に答える