web-dev-qa-db-ja.com

実装前にインターフェースAPIを作成する必要がありますか?

私は最近、より「組織化された」プログラミングを掘り下げており、実装ではなくインターフェイスにプログラミングする必要があることを学んでいます。それを念頭に置いて、可能な場合は実装を記述する前に、インターフェイスでプロジェクトを「スケッチ」する方が良いでしょうか?

これが当てはまる場合、サードパーティのライブラリ(Lidgrenなど)を使用している場合、それらもインターフェイスでラップし、IOCコンテナで解決する必要がありますか、それとも問題ありませんか。それらをインターフェースに公開しますか?

14
Dan Pantry

残念ながら、これは多くの場合、個人の好みに帰着します。

しかし、これまでに説明したことは良さそうです。実際、もし望むなら(そして私がお勧めします)、次のアプローチを使うことができます:

  1. アプリケーションスケルトンをインターフェイス、抽象クラス(スタブ)、およびクラス(スタブ)として記述します。
  2. それらのインターフェースとスタブに対してテストを記述します(今のところ失敗します)
  3. 実装を記述します(実装が完了すると、テストは合格します)。

あなたはより「組織化された」コードを書くことに焦点を合わせています。 TDDをフォローすることで、これが可能になります。

追加のポイント:

  • IoCコンテナは便利です。それらとDIをできるだけ使用します。
  • Doサードパーティのライブラリをラップします。これにより、コード(ユーザーが制御するコード)とサードパーティのコード(ユーザーが制御しないコード)の間の結合が緩和されます。
8
MetaFight

はい。既知の実装ではなく、インターフェイスに対してコーディングする必要があります。また、はい、独自のコードからインターフェイスを出現させるのではなく、まずインターフェイスを構築する必要があります。

両方の推奨事項の理由はほとんど同じです。コンピュータープログラミングは主に人的要因に関するものです。多くの人がこれは驚くべきことだと思いますが、考慮してください。同じようにうまく機能する同じコンピューティング問題を解決するためのほぼ無限の数の異なる方法がある。それらのほとんどすべては、それらを記述しなかった誰にとっても(または実際には少し後に)作者にとって意味をなすことは完全に不可能です。

したがって、優れたソフトウェアエンジニアリングとは、ソースコードを後で処理できるように、望ましい効果(妥当な効率で正しい計算)を実現する方法に関するものです。インターフェースとAPIは、その分野の重要な部分です。それらは、一度に1つのレベルの記述で問題について考えることを可能にします。これは、ビジネス整合性ルールについて考えるよりもはるかに簡単ですおよびリンクリストの実装について同時に考えるため、このような懸念事項の分離を強制することは、クライアントプログラマーを許可するよりも良いです。彼が好きな方法であなたのコードを使うため。

これは多くのカウボーイプログラマーにとって信じがたいことです。彼らが書くすべてを理解していて、平均的な思想家よりもはるかに優れており、「より少ない」プログラマーにトラブルを与えるすべての複雑さを処理できると確信しています。自分自身の認知限界を認識しないことは非常に一般的な現象です。これが、コード編成のベストプラクティスが非常に重要である(そして無視されることが多い)理由です。

繰り返しますが、インターフェースとAPIのバリアは、主にgoodですが、自分と協力している場合でも同様です。外部ライブラリーについては、よく考えられたAPIを持っている場合、そのライブラリーを別のライブラリーと交換する必要がない限り、それを使用しても問題はありません。それ以外の場合は、ラッパーまたは破損防止層が非常に良いアイデアになる可能性があります。

13
Kilian Foth

インターフェイスにプログラミングするのではなく、テスト駆動開発/設計(TDD)を調べてみませんか?

多くの人々はTDDをテストプラクティスと考えていますが、実際には、テストを介してコードが使用される方法をテストに公開する設計アプローチです(最初はユニットテストを介しますが、統合テストを介することもできます)。

インターフェイスへのプログラミングはツールセットの重要な武器ですが、ほとんどの場合と同様に、常に必要なわけではないため、常に適切なソリューション/技術/実践であるとは限りません。必要な場所でインターフェースをプログラミングする必要があります。

TDDを使用すると、そのようなインターフェースがどこで重要であり、率直に言って重要ではない場所を探るように強制されます。そして最後に、コードベース全体で非常に優れた単体テストのセットを用意する必要があります。

サードパーティのライブラリの使用に関しては、必要に応じて独自の抽象化でそれらをラップすることを強くお勧めします。 APIのクライアントにそれらについて「知らせ」ないでください。

幸運を!

[編集:megaflightの答えを見た-完全に同意する]

4
rupjones

やり過ぎだと思います。 APIのユーザーが何かを特定の方法で実装/使用する必要がない場合は、省略します。インターフェイスはコントラクトです。必要ない場合は、なぜコントラクトを指定するのですか?

インターフェースを使いすぎていると思います。ほとんどの場合必要とされない複雑さの層を追加します。

2
Kyle Johnson

ほとんどの場合、契約に反してプログラミングすることをお勧めします。そのコントラクトはインターフェースである必要はなく、代わりにクラスで実行できます。私の意見では、ユニットテストの懸念とフレームワークのモックが原因で、DIとともにインターフェイスがやや使いすぎになっています。

私は個人的に、契約を1つ以上実装する可能性がある、または実際に実施する可能性がある場合にのみ、インターフェースを導入することを好みます。インターフェイスは、データアクセスを抽象化したいリポジトリに最適ですが、比較的柔軟性が低い可能性が高い標準のビジネスロジックにはおそらくそれほど適していません。

現在、インターフェースがないと、特に純粋主義者にとって、ユニットテストで問題が発生する可能性があります。しかし、私はプログラムの内部依存関係ではなく、プログラムの外部依存関係をモックすることに興味があります。テストでコードの検証を実行し、コード構造をエコーし​​ないでください。

1
Peter Smith