dofactory 、wikipedia、多くのサイトで多くの記事を読みました。ブリッジパターンと戦略パターンの違いについてはわかりません。
どちらも抽象化をその実装から切り離し、実行時に実装を変更できることを知っています。
しかし、どの状況で戦略を使用すべきか、どの状況でブリッジを使用すべきかはまだわかりません。
セマンティクス。 wikipedia から:
StrategyパターンのUMLクラス図は、Bridgeパターンの図と同じです。ただし、これら2つの設計パターンは、意図が同じではありません。戦略パターンは行動を意味しますが、ブリッジパターンは構造を意味します。
コンテキストと戦略の結合は、ブリッジパターンの抽象化と実装の結合よりも緊密です。
私が理解しているように、外部ソースから提供できる動作を抽象化するときに戦略パターンを使用しています(たとえば、configはプラグインアセンブリを読み込むように指定できます)。使用するときはブリッジパターンを使用していますコードを少し見やすくするための同じ構成体。実際のコードは非常によく似ています-わずかに異なる理由でパターンを適用しているだけです。
ブリッジパターンは構造的なパターンです(ソフトウェアコンポーネントをどのように構築しますか?)。戦略パターンは動的なパターンです(ソフトウェアで動作を実行する方法を教えてください)。
構文は似ていますが、目標は異なります:
戦略:
意図は実行時に動作を交換する能力です
class Context {
IStrategy strategyReference;
void strategicBehaviour() {
strategyReference.behave();
}
}
ブリッジ
その目的は、抽象化を実装から完全に切り離すことです
interface IAbstraction {
void behaviour1();
.....
}
interface IImplementation {
void behave1();
void behave2();
.....
}
class ConcreteAbstraction1 implements IAbstraction {
IImplementation implmentReference;
ConcreteAbstraction1() {
implmentReference = new ImplementationA() // Some implementation
}
void behaviour1() {
implmentReference.behave1();
}
.............
}
class ConcreteAbstraction2 implements IAbstraction {
IImplementation implmentReference;
ConcreteAbstraction1() {
implmentReference = new ImplementationB() // Some Other implementation
}
void behaviour1() {
implmentReference.behave2();
}
.............
}
Bridge:(構造パターン)
ブリッジパターンは、抽象化と実装を分離し、両方を独立して変更できるようにします。
次の場合にこのパターンを使用します。
戦略:(行動パターン)
戦略パターンを使用すると、実行時にアルゴリズムのファミリから複数のアルゴリズムを切り替えることができます。
次の場合に戦略パターンを使用します。
関連記事:
私は同じことを考えていましたが、最近、ブリッジを使用する必要があり、ブリッジは戦略を使用し、コンテキストを抽象化して、後でクライアントを変更せずにさらに変更を加えることができることに気付きました。抽象化なしでStrategyを使用する場合、設計はそれほど柔軟ではなく、後でクライアントを変更する必要があります。しかし、ブリッジ全体を使用すると、設計はさらに柔軟になります。ここで、StrategyからBridgeへの移行がどのように柔軟性を高めるかを確認できます。また、今では「ビザ」と「マスター」はカードだけでなく、電話とチップでも利用できると仮定しています。ブリッジを使用すると、そのサポートを追加するのがはるかに簡単になります。
デザインパターンタイプ
ブリッジ (構造)
リモコンを取ります。リモコンにはボタン1〜6があります。これは、上の図の具象クラスです。各ボタンは、リモコンがテレビまたはDVDに使用されているかどうかによって異なります。各ボタンの機能は、実装者インターフェースによって実装から抽象化されます。
これにより、各デバイスのリモコンの動作を変更できます。
戦略 (行動)
戦略では、リモートシナリオを検討していました。 「状態」とは、コンテキストの状態参照を変更することでスワップアウトするリモート全体です。 「concreteStateA」(TVリモート)「concreteStateB」(DVDリモート)。
追加の読み物:
Willcodejavaforfoodの答えに加えて、実装において同じにすることができます。ただし、戦略を使用してソート戦略などの戦略を交換し、ブリッジを使用して2つのオブジェクト(データベースラッパーとネットワークアダプターなど)の実装をブリッジして、クライアントコードが同じAPIに対して動作するようにします。それで、命名は実際にそれをすべて言います
Strategyパターンは行動決定に使用され、Bridgeパターンは構造的な決定。
Brigdeパターンは実装の詳細から抽象要素を分離し、Strategyパターンアルゴリズムの互換性を高めることに関心があります。
Swiftの戦略パターン:
protocol PrintStrategy {
func print(_ string: String) -> String
}
class Printer {
let strategy: PrintStrategy
init(strategy: PrintStrategy) {
self.strategy = strategy
}
func print(_ string: String) -> String {
return self.strategy.print(string)
}
}
class UpperCaseStrategy: PrintStrategy {
internal func print(_ string: String) -> String {
return string.uppercased()
}
}
class LowerCaseStrategy: PrintStrategy {
internal func print(_ string: String) -> String {
return string.lowercased()
}
}
var lower = Printer(strategy: LowerCaseStrategy())
lower.print("I love Software Patterns")
var upper = Printer(strategy: UpperCaseStrategy())
upper.print("I love Software Patterns")
Swiftのブライドパターン:
protocol Appliance {
func run()
}
protocol Switch {
let appliance: Appliance {get set}
func turnOn()
}
class RemoteControl: Switch {
var appliance: Appliance
init(appliance: Appliance) {
self.appliance = appliance
}
internal func turnOn() {
appliance.run()
}
}
class TV: Appliance {
internal func run() {
print("TV is ON")
}
}
class Stereo: Appliance {
internal func run() {
print("Stereo is ON")
}
}
var tvRemote = RemoteControl.init(appliance: TV())
tvRemote.turnOn()
var stereoRemote = RemoteControl.init(appliance: Stereo())
stereoRemote.turnOn()
パターンの比較(意図の違いなど)について既に述べたことに追加するために、ブリッジパターンも意図的に構造化され、抽象化階層側が変化するようにします。 C#のような言語では、これは、既存の消費者に問題を引き起こさない意図されたバリエーションを許可する方法として、仮想メソッドを含む抽象化ベースがあることを意味します。それ以外は、2つのパターンがほとんどの部分で同一に見える場合があります。
Strategy patternのウィキから
StrategyパターンのUMLクラス図は、Bridgeパターンの図と同じです。ただし、これら2つの設計パターンは、意図が同じではありません。戦略パターンは行動を意味しますが、ブリッジパターンは構造を意味します。
コンテキストと戦略の結合は、ブリッジパターンの抽象化と実装の結合よりも緊密です。
戦略パターンは、実行時にアルゴリズムまたは戦略をプラグインする場合に使用されます。パターンのカテゴリは、オブジェクトの動作を扱うことも意味します。一方、ブリッジは構造パターンであり、オブジェクトの構造階層を処理します。それらの間に洗練された抽象化を導入することにより、抽象化を実装から分離します。洗練された抽象化は、プラグインされたランタイム戦略と混同される可能性があります(In Strategyパターン)。ブリッジパターンは、n個のクラスの作成を回避するメカニズムを提供することにより、構造的な側面を扱います。
戦略パターンについては、実装のみが異なります。
クラスAが、利用可能な複数の実装を持つクラスBを使用しているとします。そのため、その場合、Bは実行時に提供される実際の実装で抽象化されます。これは戦略パターンです
A自体が抽象的である場合。 AとBの両方が異なる場合があります。ブリッジパターンを使用します。
それらが使用されているコンテキストでは、それらの間にわずかな違いがあると思います。
ブリッジパターンを使用して、両方がより大きな概念に属する直交概念を分離します。通常、複数の抽象化が含まれます。
IMO、戦略パターンはよりシンプルまたはよりフラットです。確かにOCPに役立ちますが、必ずしもブリッジパターンのような別のより大きなコンセプトの一部である必要はありません。