web-dev-qa-db-ja.com

インターフェイスベースのプログラミングの使用が動作に限定されているように見えるのはなぜですか?

私は継承対実現対構成について少し考えてきました。ここにすべての詳細を投稿するつもりはありません。ユニットテストを容易にするためのインターフェイスの作成について話しているのではないので、疑問に思っていました。インターフェイスベースのプログラミングが、IPettable(動物の場合)、IEditable(ユーザーコントロールの場合)などの一般的な動作のグループ化に焦点を当てているように見えるのはなぜですか。 、ISubmitable(フォームの場合)など。インターフェイスベースのプログラミングの使用が、本質ではなく動作に限定されているように見えるのはなぜですか。インターフェースを実際に使用して、動作をあまり実現することはできませんが、動作とは関係のない常識的な物理的類似性を実現することができますか?インターフェイスベースのプログラミングには、これを行うとは思わない制限機能があるわけではありません。これは、可能な方法のほんの一部でインターフェースを使用する傾向があることを意味します。では、どうしてですか?

1
CarneyCode

これは制限ではなく、むしろ利点です。インターフェイスは、インターフェイスの利用者の生活を楽にするように作成する必要があり、消費者はオブジェクトで何ができるかに関心があります。したがって、成功するインターフェースとは、オブジェクトが他の人によってどのように使用されるかと密接に一致するインターフェースです(例を使用するために、ペッティング、編集、または送信することによって)。

いずれにせよ、JavaverseのSerializableや.NETの世界のIDisposableなど、実際にはマーカーインターフェイスが存在します。個人的に私はいつも彼らが一種の厄介だと思っていましたが、あなたのマイレージは異なるかもしれません。

4
CurtainDog

インターフェイスは、プレゼンテーションコントラクトを効果的に定義し、非常に抽象的なレベルでクラス間の互換性を提供する手段を提供します。インターフェイスを使用すると、事実上"このクラスはある方法で定義されますが、別の方法で使用して別のクラスと互換性を持たせることができます"と言っています。

基本的に、ユースケースを定義しています。オブジェクト自体にアクセスできる場合は、通常、インターフェイスを介してオブジェクトにそのプロパティを要求することはありません。ただし、通常は、システム内の他のクラスタイプの動作と一貫性のある方法でオブジェクトを動作させるように要求します。これにより、それぞれを呼び出して、同様の一貫した方法で動作することが期待できます。それがポリモーフィズム101です。

さて、少し矛盾します。先ほど、通常はインターフェースを介してクラスにプロパティを要求しないと言いました。定義されたインターフェースの意図は、確かにそのように動作することです。ただし、canクラスがインターフェイスを介してプロパティを提供するように要求しますが、プロパティ構文の代わりにメソッドを使用します。この場合、getterメソッドを介して値を取得できるように、(インターフェイスを介して)クラスにbehaveを要求しています。これは古典的な要求/応答の動作であり、インターフェイスの基本的な動作の性質と完全に一致していますが、クラスを単なる単純なデータ構造、または共通のインターフェイスを介して他のクラスと互換性のあるタイプであるかのように扱う機能を妨げるものではありません。抽象化。

Getter/Setterの動作は、すべての内部変数にカプセル化を提供することにも対応しています。 Delphiなどの言語、および現在は自動プロパティを備えたC#は、線をぼかし、プロパティを単なる変数のように動作させる傾向がありますが、実際には、各プロパティの内部には、各プロパティの内部にゲッターとセッターのメソッドがあります。 。そうでない場合は、カプセル化を維持するために必要です。

この観点から見ると、インターフェースは制限付き動作のみに限定されていません。それらは事実上それによって拡張であり、次にそれらを実装するクラスを拡張します。

1
S.Robins

インターフェイスは、いくつかのデザインパターンを構築するために使用できる小さなビルディングブロックです(デザインパターン、ガンマなどを参照してください。、または 要約についてはhttp://en.wikipedia.org/wiki/Design_pattern_(computer_science ))。さまざまな種類のデザインパターンをスキャンすると、インターフェイスのさまざまな使用方法がわかります。

特に、デコレータパターンとファサードパターンを比較することをお勧めします。あなたが持っている例は、ほとんどすべてのデコレータ、機能を追加する小さなアドオンです。対照的に、ファサードは、実装されるアクションの予想セットを定義するコントラクトのようなものです。 (注:これらは両方とも簡略化された説明です。提案された参考資料でこれらを確認してください)。インターフェイスは、これらのパターンの両方を実装するために使用でき、Javaなどのインターフェイス駆動型言語でそのように実装されることがよくあります。

1
smithco

私はあなたが探しているのは一般的なプログラミングであるという印象を受けています...しかし確かではありません:/

一般的なプログラミングでは、次のものがあります。

interface Pettable {
  void eat(Food f);
  void move(Direction, Distance);
}

次に、クラスを作成します。

class Cat {
  void eat(Food f);
  void move(Direction, Distance);
}

また、Pettableを受け入れるメソッドは、Catから派生したためではなく、単にモデル化され、コンパイラがそれを認識するため、即座にPettableを受け入れます。

一部の言語はさらに「一般的」であり、インターフェイスを宣言する必要はまったくありません。むしろ、メソッドの要件から派生します(コンパイル時のテンプレートのC++、Python atランタイム)。

1
Matthieu M.

OOPは動作に限定されず、特性が含まれているため、インターフェイスも含まれます。例えばIPersonは、Characterstics {a.k.aプロパティ}とbehaiours {a.k.aメソッド}の両方を持つことができます。インターフェイスベースのプログラミングは、現実世界の問題をプログラミング世界に抽象化する傾向がありますが、一方で、継承/実現/構成は現実世界を作動させます。要するに、インターフェースはコントラクト/タイプを定義します{誰が履行するかは、そのタイプになります。}一方、クラス(継承/構成)はそれらのコントラクトの実装を定義します。例えば私がインターフェースを持っていると言うICandianブール値を持っているBornInCanada、そのインターフェースを定義することは、カナダ人であるためにはブール値を提供しなければならないという契約を定義するだけです。 BornInCanadaの実装を与える人は、そのタイプ、つまりICanadianになります。あなたが私の主張を理解したことを願っています。

0
Furqan Hameedi