web-dev-qa-db-ja.com

私が書くすべてのクラスはインターフェイスに準拠する必要がありますか?

私はTypeScriptでゲームを書いていて、「 インターフェイスベースのプログラミング 」という考え方に固執しようと決心しました。オブジェクトの実装。

私は十分な数のインターフェースとそれらを実装するクラスを作成し、一歩下がって、クラスが単純であることを認識しました。実装を変更する必要はないでしょう。クラスは(Phaser.Spriteタンクのように機能するように制限された方法で)。

次に、数年前に [〜#〜] yagni [〜#〜] のアイデアについて読んだことを覚えています。これは、基本的に、コードを過度に設計して、決して許可しないものを含めることはできません。使用する。

ベストプラクティスに従って、すべてのクラスがインターフェイスを実装する必要がありますか、それとも将来的にスワップアウトされる可能性があると予想されるクラスに限定する必要がありますか?

10
Carcigenicate

インターフェイスを持つ理由は、それが多態性を単純化するためです。つまり、実際の実装を知るのではなく、コントラクトでインスタンスを送信できます。たとえば、「Reader」をメソッドに送信すると、そのような呼び出されたメソッドは「read()」メソッドを使用できます。インターフェース「リーダー」を宣言することにより、指定したメソッドを実装することにより、任意のオブジェクトをこの規約に準拠させることができます。この方法では、コントラクトの基礎となるオブジェクトが完全に異なる場合でも、呼び出し元は特定のメソッドが存在すると想定できます。

これにより、基本クラスからポリモーフィズムが分離され、コントラクトを暗黙指定することにより、クラスチェーンの境界間でも可能になります。

今...これは、複数の継承チェーンが同じように動作する必要がある場合、または他のユーザーに渡したい共通の動作を持つ多くの基本クラスがある場合にのみ役立ちます。

継承チェーンが1つ(ベースクラス->サブクラス)またはベースのみの場合、または実際に関連オブジェクトを他のユーザーに渡したり、一般的に使用したりする必要がない場合は、インターフェイスの実装を追加しないでください。役に立たない。

6

実際にインターフェースが必要かどうかわからない場合は、おそらく必要ありません。これはYAGNI原則の中核です。 When実装を交換できるようにする必要がある場合は、インターフェースを導入します。

7
JacquesB

すべてのクラスのインターフェースを作成するのは少々やり過ぎです。純粋にオブジェクト指向の観点から見ると、すべてのクラスにはすでにインターフェースがあります。インターフェースは、クラスに公開されているメソッドとデータメンバーにすぎません。

通常、「インターフェース」を使用して、「a Java interfaceキーワードを使用して定義されたクラス」または「パブリックで純粋な仮想関数のみを含むC++クラス」を意味します。これらは有用な抽象化です。なぜなら、それらはクラスのインターフェースをその実装から切り離すからです。

これを念頭に置いて、適切な場合はインターフェースを使用してください。

  • インターフェイスには複数の実装がありますか?もしそうなら、この状況mayは、一般的な公開メソッドをインターフェースに抽出する候補となります。

  • 私のモジュールの内部動作を知らないはずの他のモジュールに潜在的なインターフェースの実装を引き渡すでしょうか?モジュール間のタッチポイントのサイズが小さくなるため、ここではインターフェースが役立ちます。

上記のイタチの単語に注意してください。「可能性がある」は候補であり、「可能性がある」は有用です。特定の状況で「はい」または「いいえ」と言う厳格な規則はありません。

そうは言っても、すべてにインターフェースを用意するのは、やりすぎかもしれません。このパターンが見られる場合は、次のようになります。

interface I {
  int getA()
  int getB()
  ...
  int getY()
  int getZ()
}

class C : I {
  int getA() { ... }
  int getB() { ... }
  ...
  int getY() { ... }
  int getZ() { ... }
}
6
user22815

新しい開発者にとって、「ベストプラクティス」であると言われたからといって、インターフェイスを単に追加するという不便さであると考えるのは非常に魅力的です。もしあなたが盲目的にこれをしているなら、それは 貨物カルトプログラミング をたたきます。

一連のクラスをまとめて投げるのではなく、大規模な開発用のインターフェースを検討する必要がある非常に良い理由がいくつかあります。

モッキングフレームワーク

さまざまなレイヤーのオブジェクトを作成せずにマルチレイヤーアプリケーションをテストする場合は、疑いなくモックフレームワークを使用してレイヤーをモックアウトする必要があります。ここではインターフェースが広く使用されています。

依存性注入

追加した膨らみのために彼らはやや支持を失いましたが、アイデアは健全です-インターフェースに基づいてコンクリートを単純に交換する機能。この原則は、ファクトリーパターンなどの多くのデザインパターンにも見られます。


これらのアプローチは [〜#〜] d [〜#〜]SOLIDの原則 にまとめられています。これの摩擦は、具体化ではなく抽象化を使用することです。

デザインパターン自体と同様に、いつ使用するかは判断の呼びかけです。要点は、インターフェースをクラスに貼り付けるだけでなく、インターフェースの有用性を理解することです。 DIPとYAGNI here のさまざまなメリットについての良い議論があります。

5
Robbie Dee