プログラマーが実装をインターフェイスから分離したいのはなぜですか?


18

ブリッジ設計パターンは、プログラムのインターフェースから実装を分離します。

なぜこれが有利なのですか?


防ぐには、漏洩の抽象化
SK-ロジック

1
これはすでに誰もが理解しているように見えますが、新しい視聴者にとって、Bridge Designは「プログラム」の実装とインターフェースではなく、プログラムの一部、おそらく小さな部分についてです。プログラム全体は、インターフェイスと実装のコレクションになります(各インターフェイスには1つ以上の実装があります)。最初の文は、おそらく次のようになります。「ブリッジ設計パターンは、すべてのソースコード全体で、インターフェイスを実装から分離します。」
ラルフシャピン

回答:


35

これにより、インターフェイスとは無関係に実装を変更できます。これは、要件の変化に対処するのに役立ちます。

典型的な例は、インターフェースの下のストレージ実装を、システムの他の部分を変更せずに、より大きく、より良く、より速く、より小さく、または別の方法で置き換えることです。


23

ダニエルの答えに加えて、ポリモーフィズムなどの概念を介してインターフェイスを実装から分離することにより、異なる方法で同様のことを行う同じインターフェイスの複数の実装を作成できます。

たとえば、多くの言語には、標準ライブラリのどこかにストリームという概念があります。ストリームは、シリアルアクセス用のデータを保持するものです。読み取り(ストリームから次のXバイトを読み込む)と書き込み(ストリームにXバイトのデータを追加する)、および場合によっては3番目のシーク(ストリームの「現在位置」をリセットする)の2つの基本操作があります。新しい場所に)。

これは十分に単純な概念ですが、それでできることはすべて考えてください。最も明白な方法は、ディスク上のファイルを操作することです。ファイルストリームを使用すると、ファイルからデータを読み取ったり、ファイルに書き込むことができます。しかし、代わりにネットワーク接続を介してデータを送信する場合はどうでしょうか?

実装に直接依存している場合、同じデータをファイルに保存するか、ネットワーク経由で送信するために、2つの完全に異なるルーチンを作成する必要があります。ただし、ストリームインターフェイスがある場合は、データを送信する必要がある特定の詳細をカプセル化する2つの異なる実装(FileStreamおよびNetworkStream)を作成できます。その後、ファイルの保存を処理するコードを1回記述するだけで済みます。 。突然、あなたSaveToFileSendOverNetworkルーチンははるかに簡単です:彼らは適切なタイプのストリームを設定し、それをSaveDataルーチンに渡すだけで、ストリームインターフェースを受け入れます-それが実行できる限り、どのタイプを気にする必要はありません書き込み操作-データをストリームに保存します。

また、データ形式が変更された場合、複数の異なる場所で変更する必要がないことも意味します。ストリームを受け取る1つのルーチンでデータ保存コードを集中化する場合、それが更新が必要な唯一の場所であるため、両方を変更する必要があるときに1つの場所を変更するだけで誤ってバグを導入することはできません。したがって、インターフェイスを実装から分離し、ポリモーフィズムを使用すると、コードが読みやすく、理解しやすくなり、バグが発生しにくくなります。


1
これは、OOPの最も強力な機能の1つです。私はちょうど...それを愛する
ラドゥMurzea

1
プレーンインターフェイスを使用するこの異なる形式はどうですか?
vainolo

@Vainolo:コードの再利用に役立ちます。複数のタイプのストリームがある場合でも、それらはすべて互いに同じことをたくさん行います。IStreamインターフェースから始める場合、すべてのストリームの機能セット全体を再発明する必要があります。ただし、基本抽象ストリームクラスから開始すると、共通の状態と機能をすべて保持し、子孫に個別の機能を実装させることができます。
メイソンウィーラー

2
@RaduMurzeaこれはOOPに固有のものではありません。型クラスを使用すると、まったく同じOOP方式で同じことができます。
ウェス

@Wesは、ちょうど同じことを言いたかったので、コメントを読みました。
ジェゲドゥス

4

ここには、2つの非常に異なる質問がありますが、それらは関連しています。

より一般的な質問はタイトルにあるものです。なぜ一般的な実装からインターフェイスを分離するのでしょうか。2番目の質問は、ブリッジパターンが役立つ理由です。ブリッジパターンは、インターフェイスを実装から分離する特定の方法であり、他の特定の結果もあるため、これらは関連しています。

一般的な質問は、すべてのプログラマーが理解するために不可欠なものです。これは、プログラムの変更がどこにでも伝播するのを防ぎます。これを使わずにプログラムできる人間は想像できません。

プログラミング言語で単純な加算ステートメントを書くとき、それはすでに抽象化されています(マトリックスまたはそのようなものを追加するために演算子のオーバーロードを使用していない場合でも)コンピューターの回路上。インターフェース(「3 + 5」など)が実装(マシンコードの束)から分離されていない場合、実装が変更されるたびにコードを変更する必要があります(新しいプロセッサ)。

単純なCRUDアプリケーション内であっても、すべてのメソッドシグネチャは、広い意味で、その実装へのインターフェイスです。

これらの種類の抽象化はすべて同じ基本的な目標を持っています-呼び出し元のコードに、可能な限り多くの情報を実装者に提供する最も抽象的な方法で意図を表現させます。これにより、それらの結合が最小限に抑えられ、コードを可能な限り変更する必要がある場合のリップル効果が制限されます。

簡単に聞こえますが、実際には複雑になります。

ブリッジパターンは、実装の特定のビットをインターフェイスに分離する特定の方法です。パターンのクラス図は、説明よりも有益です。これは、ブリッジというよりプラグ可能なモジュールを持つ方法に似ていますが、インターフェースより前にモジュールが作成された場所でよく使用されるため、ブリッジと名付けました。そのため、類似した既存の実装に共通のインターフェースを作成することで、一種の「橋渡し」となり、コードを実装のいずれかと連携させることができます。

したがって、ワードプロセッサにアドオンを作成したいが、複数のワードプロセッサで動作するようにしたいとします。必要なワードプロセッサベースの機能を抽象化するインターフェイスを作成します(これらは変更できないため、各ワードプロセッサで実装可能でなければなりません)。その後、アプリケーションはそのインターフェイスを呼び出すことができ、各ワードプロセッサの詳細について心配する必要はありません。

各クラスは実際にはクラス階層である可能性があるため(実際には、抽象ワードプロセッサだけでなく、それぞれに具体的な実装を備えた抽象的なDocument、抽象的なTextSelectionなどが存在する可能性があるため)、実際にはそれよりわずかに詳細ですが、同じ考え。

この場合、抽象化レイヤーが、複数の基礎となるシステムに同じインターフェースを提供することに焦点を合わせていることを除いて、外観に少し似ています。

具体的な実装者はメソッドまたはコンストラクターに渡され、呼び出される実際の実装を決定するため、Inversion Of Controlに関連しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.