39

私はこの質問が以前に尋ねられたことを知っています(例えば、ブリッジパターンと戦略パターンの違いは何ですか?)。

しかし、誰かが明確な例を使用して、違いは何であり、どのような場合に一方を他方から選択する必要があるのか​​を説明してもらえますか?概念的な理論ではなく、より実用的な「現実の」シナリオをいただければ幸いです。

4

9 に答える 9

46

ブリッジ パターンは、抽象化と実装を区別して、2 つが独立して変化できるようにします。の例を使用します

Java のパターン、第 1 巻: UML で示される再利用可能な設計パターンのカタログ、第 2 版

体重計や速度測定デバイスなどに見られるような物理センサーにアクセスするクラスを提供する必要があります。各センサーは数値を生成しますが、数値は異なる意味を持つ可能性があります。はかりの場合は重量を意味し、速度測定装置の場合は速度を意味する場合があります。

そのため、センサー抽象クラスを作成して、すべてのセンサーとさまざまなタイプのセンサーのさまざまなサブクラスの間の共通性を表すことから始めることができます。これは堅牢な設計であり、将来さらに多くのタイプのセンサーを提供できるようになります。

ここで、さまざまなメーカーからセンサーが提供されているとします。メーカー X 用とメーカー Y 用に別のセンサー クラスの階層を作成する必要があります。ここでの問題は、クライアントがメーカー間の違いを知る必要があることです。そして、もしあなたがサードメーカーをサポートすることに決めたら...?

解決策は、主な抽象化階層を提供することです。Sensor 抽象クラスと、SpeedSensor や WeightSensor などのサブクラス。次に、抽象化と実装の間に存在するインターフェイス (ブリッジ) を提供します。したがって、SensorInterface、WeightSensorInterface、および SpeedSensorInterface があり、各具体的なセンサー クラスが提供する必要があるインターフェイスを指定します。抽象化は実装については認識していませんが、インターフェースについては認識しています。最後に、製造元ごとに具体的な実装を作成できます。つまり、XSensor、XWeightSensor と XSpeedSensor、YSensor、YSpeedSensor と YWeightSensor です。

クライアントは抽象化のみに依存しますが、任意の実装をプラグインできます。したがって、このセットアップでは、具象クラスを変更せずに抽象化を変更でき、抽象化を気にせずに実装を変更できます。

ご覧のとおり、これはクラスを構造化する方法を説明しています。

一方、ストラテジーは、実行時にオブジェクトの動作を変更することに関係しています。いくつかの異なる種類の武器を所有するキャラクターのゲームの例を使用するのが好きです. キャラクターは攻撃することができますが、攻撃の動作はキャラクターがその時点で保持している武器に依存し、これはコンパイル時に知ることができません。

そのため、武器の動作をプラグ可能にして、必要に応じてキャラクターに挿入します。したがって、行動パターン。

これら 2 つのパターンは、異なる問題を解決します。戦略はアルゴリズムを交換可能にすることに関係しており、ブリッジは実装から抽象化を分離して、同じ抽象化に複数の実装を提供できるようにすることに関係しています。つまり、橋は構造物全体に関係しています。

役に立つかもしれないいくつかのリンクを次に示します。

  1. ブリッジパターン
  2. 戦略パターン
于 2011-05-03T03:06:58.943 に答える
35

これは説明が難しいと言えます。それを使用して理解している多くの人々は、初心者に説明するのに苦労しています.

アナロジーの観点から考える私のような人のために:

戦略パターン

つまり、戦略は一種の 1 次元の概念です。選択する戦略の 1 次元配列を考えてみてください。

例 1: 配管工のツール

戦略パターンは、パイプの詰まりを取り除くためにさまざまなツールを持っている配管工のようなものです。仕事は毎回同じです。パイプの詰まりを解消することです。しかし、これを行うために彼が選択するツールは、状況によって異なります。多分彼は 1 つを試してみて、それがうまくいかない場合は別のものを試します。

このアナロジーでは、「パイプの詰まりを解消する」は、戦略の 1 つを実装する方法です。スネーク ブラシ、パワー オーガー、ドレーンは具体的な戦略であり、配管工はメソッドを含むクラスです (ほとんどの図では "Context" とラベル付けされています)。

ここに画像の説明を入力

例 2: 多ビット ドライバー

または、マルチビット ドライバーの交換可能なビットを考えることができます。それらは、何かを台無しにするという目前の仕事に合わせて、実行時に変更されることを意図しています。

ここに画像の説明を入力

ブリッジパターン

つまり、橋は二次元の概念です。1 つの次元 (行) は実装する必要があるメソッドのリストであり、2 番目の次元 (列) はそれらのメソッドのそれぞれを実装する実装者であると考えてください。

例 1: アプリとデバイス

ブリッジ パターンは、さまざまな通信手段 (電子メール、テキスト、Google 音声、電話、スカイプ) と、これらのさまざまな通信手段 (PC、タブレット、スマート フォン) で通信できる多くのデバイスを持っている人のようなものです。電話。

通信するためのさまざまな方法 (電子メール、テキスト、電話) は、抽象インターフェイスのメソッドになります。これを「CommunicationDevice」と呼びましょう。このパターンでは、CommunicationDevice が実装者です。このアナロジーの各デバイス (PC、タブレット、スマートフォン) は、これらすべてのメソッド (電子メール、テキスト、電話) を実装する ConcreteImplementor です。

ここに画像の説明を入力

例 2: Odbc データベース ドライバーと odbc 関数

bridge のもう 1 つのわかりやすい例は、Windows の odbc または oledb データベース ドライバー モジュールです。これらはすべて、同じ標準の「データベース ドライバ」インターフェイスでさまざまなメソッドを実装していますが、そのインターフェイスを異なる方法で実装しています。Sql Server などの同じデータベースを使用している場合でも、Sql Server と対話できるさまざまなドライバーが存在しますが、内部ではさまざまな方法で行われます。

例 3: メソッド (行) を実装する実装者 (列)

メソッド (行) を実装する実装者 (列)

于 2015-04-09T17:58:14.267 に答える
4

作戦パターン

このパターンにより、実行するアルゴリズムは、それを使用するクライアントとは独立して変化します。つまり、特定の状況で実行する固定アルゴリズムを使用する代わりに、実行時にオンザフライで多くのアルゴリズムの中から 1 つを選択できます。これには、ホスト クラスからアルゴリズムを削除し、別のクラスに配置することが含まれます。

たとえば、ある都市から別の都市に移動したい場合、バスに乗る、レンタカーを借りる、電車に乗るなど、いくつかの選択肢があります。したがって、選択された各交通手段は、実行される個別のアルゴリズムに変換されます。選択される転送モードは、実行時に決定されるさまざまな要因 (コスト、時間など) によって異なります。言い換えれば、実行するために選択された戦略はその場で決定されます。

別の例として、に基づくSortedListクラス (メイン コントローラ)を実装したいとします。戦略は、並べ替えに使用する方法です (MergeSort、QuickSort など)。Sortsstrategy

ブリッジパターンとの比較

主な違い (両方のパターンの UML は同じですが) は、ブリッジ パターン (構造パターン) とは異なり、戦略パターンは動作パターンであることです。構造パターンは、オブジェクトが構成、関連付け、または継承されてより大きなオブジェクトを形成する方法を示唆しています。つまり、オブジェクトの構成に焦点を当てています。行動パターンはアルゴリズムやビジネス ロジックを扱いますが (オブジェクトの作成そのものではありません)、つまり、オブジェクト間のコラボレーションに焦点を当てています。

ほとんどのアルゴリズムは、単一のインスタンスの作成のみを必要とする静的クラスまたはシングルトン クラスとして実装できることに注意してください (つまりnew、戦略が設定されるたびに呼び出されるわけではありません)。

2 つのパターンの実装を詳しく見ると、ブリッジ パターンではオブジェクトの具体的な実装を作成してから呼び出しを作成することがわかります。

// Set implementation and call
// i.e. Returns (creates) the concrete implementation of the object, 
// subsequently operation is called on the concrete implementation
ab.Implementor = new ConcreteImplementorA(); 
ab.Operation();

一方、戦略パターンの場合、アルゴリズムの具体的な実装を直接使用するのではなく、戦略を実行するコンテキストを作成します。

// Set the context with a strategy
// i.e. Sets the concrete strategy into the context, concrete implementation of the class not 
// directly available as a data object (only the algorithm is available).    
context = new Context (new ConcreteStrategyA());     
context.contextInterface();

// Strategy can be reused instead of creating a new instance every time it is used.
// Sort example
MergeSort mergeSort = new MergeSort();
QuickSort quickSort = new QuickSort();
...
context = new Context (mergeSort);
context.Sort();
...
context = new Context (quickSort);
context.Sort();
...
context = new Context (mergeSort);
context.Sort();
于 2011-05-03T01:08:07.460 に答える
1

どちらのパターンも、インターフェイスを実装から分離します。主な違いは、Bridge パターンが継承を使用する ("is a") のに対し、Strategy パターンは合成を使用する ("has a") ことだと思います。

ブリッジパターン:

class Sorter abstract
{ 
   virtual void Sort() = 0;
}

// MergeSorter IS A Sorter
class MergeSorter : public Sorter
{
   virtual void Sort() override;
}

戦略パターン:

class SortStrategy abstract
{
   virtual void Sort() = 0;
}

// Sorter HAS A SortStrategy
class Sorter
{ 
   Sorter(SortStragety *strategy) : mStrat(strategy) {}

   void Sort() {mStrat->Sort();}

   SortStrategy *mStrat;
}
于 2013-12-11T22:50:37.220 に答える
0

リンクされた質問からの回答を暗唱させてください。

ブリッジ パターンは構造パターンです。つまり、プロジェクトのコンポーネントを構築する方法のアイデアをレイアウトします。2 レベルの抽象化を隠すために使用されます。ウィキペディア (http://en.wikipedia.org/wiki/Bridge_pattern) のサンプル コードでは、最も明確な用語で説明されています。

戦略パターンは動的パターンです。任意のワイルド関数が要件を実装できる場合、戦略パターンが使用されます。例としては、プラグインの開発とインストールを可能にするプログラムが挙げられます。ウィキペディアのページ (http://en.wikipedia.org/wiki/Strategy_pattern) では、ConcreteStrategyAdd、ConcreteStrategySubtract などのプラグインが ConcreteStrategy クラスで使用されています。そこでは、インターフェース Strategy を実装する任意のメソッドを使用できます。

于 2011-05-03T00:00:12.213 に答える