2009-03-31 3 views
8

私はcooladeを飲んで、インターフェイス、IoC、DI、TDDなどを愛しています。しかし私は、私が傾向を作るために戦わなければならないことを発見していますすべてインターフェイス!私はインターフェイスである工場を持っています。そのメソッドは、インタフェースとなる可能性のあるオブジェクトを返します(テストを簡単にするかもしれません)。これらのオブジェクトは、必要なサービスに対するDI'インターフェースです。私が見つけたのは、インターフェイスを実装と同期させておくことは、作業に追加することです。クラスにメソッドを追加するということは、クラス、インターフェイス、モックなどに追加することです。インターフェイスInsanity

私は、早すぎる?インタフェースとオブジェクトのどちらを返すべきかを知るベストプラクティスはありますか?

+0

今、みんな...コンピュータを切り替えてお互いのコードを読んでください! –

答えて

7

インターフェイスは、オブジェクトとその共同編集者の1人とのやり取りを模擬したいときに便利です。ただし、内部状態を持つオブジェクトのインタフェースには値が少なくなります。

たとえば、あるドメインオブジェクトを何らかの方法で操作するためにリポジトリと通信するサービスがあるとします。

リポジトリからインタフェースを抽出する際の明確な設計値があります。私のリポジトリの具体的な実装は、NHibernateやActiveRecordに強く結びついているかもしれません。私のサービスをインターフェイスにリンクすることによって、この実装の詳細から明確に分離することができます。それは私がIRepositoryを手に入れることができるようになりましたので、サービスのための超高速スタンドアロンユニットテストを書くこともできます。

リポジトリから戻ってきたドメインオブジェクトを考慮して、私のサービスが動作するドメインオブジェクトを考えると、価値は低くなります。私のサービスのテストを書くとき、私は実際のドメインオブジェクトを使い、その状態をチェックしたいと思うでしょう。例えば。 service.AddSomething()の呼び出しの後、何かがドメインオブジェクトに追加されたことを確認したい。ドメインオブジェクトの状態を簡単に調べることでこれをテストできます。ドメインオブジェクトを孤立してテストすると、オブジェクトに対する操作を実行して内部状態でクイズするだけなので、インターフェイスは必要ありません。例えば私の羊が眠っている場合、草を食べることは有効ですか?

最初のケースでは、我々は相互作用ベースのテストに興味があります。テスト対象のオブジェクトとそのコラボレーターとの間を通るコールをモックで傍受したいので、インターフェースが役立ちます。 2番目のケースでは、ベースのテストに興味があります。インタフェースはここでは役に立ちません。あなたが状態やインタラクションをテストしているかどうかを意識して、それがあなたのインターフェースに影響を与えるか、インターフェースの決定に影響を及ぼさないようにしてください。

(Resharperがインストールされていれば)後でインターフェイスを抽出するのが非常に安いことに注意してください。結局そのインターフェースを必要としないと決めたら、インターフェースを削除してより簡単なクラス階層に戻すことも安価です。私のアドバイスは、インターフェイスを使わずに開始し、インタラクションを模擬したいと思ったときに必要に応じて抽出することです。

IoCを画像に追加すると、より多くのインターフェイスを抽出する傾向がありますが、IoCコンテナにいくつのクラスを押し込めばいいか分かりません。一般に、これらの制限された主としてステートレスなサービスオブジェクトを保持したいとします。

6

BDUFから少し苦しんでいるようなサウンドです。

クールダウンで楽にして自然に流れましょう。

5

私は通常、「サービス」のインターフェイスを必要としていますが、「データ」に関する主なタイプは具体的なクラスにすることができます。たとえば、私はAuthenticatorインターフェイスを持っていますが、Contactクラスです。もちろん、必ずしも明確であるとは限りませんが、それは当初の経験則です。

私もあなたの痛みを感じない - それは少し戻った.hと.cファイルの暗い日に行くようなものだ...

0

インタフェースは、契約を確立する目的を持っているときに特に有用ですその場でタスクを実行するクラスを変更したい。クラスを変更する必要がない場合、インタフェースが途中で取得する可能性があります。

インターフェイスを抽出する自動ツールがあるので、後でそのプロセスの後半でインターフェイス抽出を遅らせる方がよいでしょう。

-1

最初にインターフェイスを作成しないでください。インターフェイスは必要ありません。あなたは、あなたがどのクラスのインターフェースを必要としないかを推測することはできません。したがって、無駄なインターフェイスでコードに負担をかける時間を費やす必要はありません。

しかし、リファクタリングの段階で、インターフェイスの必要があるとわかったときに、そうするように感じるときに、それらを抽出します。

Those answersでもお手伝いできます。

+1

-1のデザインは常にインターフェイスから始める必要があります。 –

6

柔軟性は価値ある目標ですが、IoCとDI(ある程度はTDDの要件です)に柔軟性を持たせることで、複雑さも増しています。柔軟性の唯一のポイントは、ダウンストリームの変更をより迅速に、より安く、より良いものにすることです。各IoC/DIポイントは複雑さを増すため、他の場所での変更をより困難にするのに貢献します。どのような領域に変更する可能性が最も高い(および/または大規模なユニットテストを必要とする)を特定し、そこ柔軟性のための計画:あなたには、いくつかの範囲をするビッグデザインアップフロントを必要な場所

これは実際にあります。変更が起こりそうもない柔軟性を排除するためにリファクタリングしてください。

ここでは、どのような種類の精度で柔軟性が必要になるかを推測できるとは言いません。あなたは間違っているでしょう。しかし、あなたは何か正しいことを得るでしょう。後で柔軟性が必要ないと分かった場合、メンテナンスの際に考慮することができます。必要な場所では、フィーチャーを追加する際に考慮することができます。

ここで、変更する可能性のある領域と変更しない領域は、ビジネス上の問題とIT環境によって異なります。ここにいくつかの繰り返し領域があります。

  1. 私はいつもあなたが非常に可変であることを 他のシステムに統合し、外部 インタフェースを検討したいです。
  2. にバックエンドを提供するコードは、ユーザーインターフェイスはUIの変更をサポートする必要があります。ただし、主に機能の変更を計画してください。スマートクライアントとWebアプリケーションの両方をサポートするなど、さまざまなUIテクノロジを使いすぎないように計画してください。使用パターンが多すぎます。異なるデータベース やプラットフォームへの移植 をコードする一方
  3. は、少なくとも企業 環境では時間の無駄 通常
    です。お問い合わせのうえ を交換する予定があるか、または ソフトウェア内で アップグレードテクノロジを使用している可能性があります。
  4. データコンテンツおよびフォーマットの変更は、トリッキーな ビジネスです:データが変更さたまに する一方、ほとんどの設計 私が悪いのハンドルそのような変更を 見てきたので、あなたは直接使用する具体的な エンティティクラスを取得します。

しかし、変更する必要があるかどうかは判断できません。

2

「アジャイル」の最も重要な原則はYAGNI(「あなたはそれが必要ではない」と思う)。言い換えれば、実際に必要になるまで、余分なコードを書かないでください。事前に書いておくと、最終的に必要なときに、要件や制約が変わってしまう可能性があります。

これらのすべては、コードを複雑にするため、理解したり変更したりするのが難しくなります。私の経験則は、できるだけシンプルなものを(シンプルでなく)シンプルに保つことと、それが課す負担を相殺するのに十分なものが得られない限り、複雑さを加えないことです。

実際にテストしていて、モックオブジェクトを持つことは非常に便利です。擬似クラスと実クラスの両方が実装しているインタフェースを決めることは忘れないでください。しかし、ある時点で有用かもしれない純粋に仮定上の理由で、あるいは正しい "オブジェクト指向設計"であるという一連のインタフェースを作成しないでください。

+0

「これらのすべてがコードに複雑さを加え、理解して変更するのが難しくなります」というステートメントで説明してください。それはあなたの答えのポイントの中核ですが、*なぜ*それが本当であるかについての理由はありません。 –

0

あなたが提供しているものに非常に依存します...あなたが内部のものを扱っている場合、「必要になるまでそれらをやってはいけない」というアドバイスが合理的です。しかし、他の開発者が使用するAPIを作成している場合は、後でインターフェースに変更することは迷惑になることがあります。

実際のところ、インタフェースをサブクラスにする必要があるインタフェースを作成することをお勧めします。これは「常にそのような場合にインターフェイスを作ってください」というものではなく、それについて考える必要があります。

これは簡単な答えです(これは内部的なものとAPIを提供する両方で機能します)。複数の実装が必要になることが予想される場合は、それをインターフェイスにします。

一般的にインターフェイスではないものは、xとyを扱うLocationクラスのようにデータを保持するだけのクラスです。それの別の実装がスリムであるということのオッズがあります。

関連する問題