Was ist der Unterschied zwischen dem Brückenmuster und dem Strategiemuster?


114

Ich habe versucht, viele Artikel über Dofactory , Wikipedia und viele Websites zu lesen . Ich habe keine Ahnung von Unterschieden zwischen Brückenmuster und Strategiemuster.

Ich weiß, dass beide eine Abstraktion von ihrer Implementierung entkoppeln und die Implementierung zur Laufzeit ändern können.

Aber ich weiß immer noch nicht, in welcher Situation ich Strategie verwenden soll oder in welcher Situation ich Bridge verwenden soll.

Antworten:


66

Semantik. Aus Wikipedia :

Das UML-Klassendiagramm für das Strategiemuster entspricht dem Diagramm für das Bridge-Muster. Diese beiden Entwurfsmuster sind jedoch in ihrer Absicht nicht gleich. Während das Strategiemuster für das Verhalten gedacht ist, ist das Brückenmuster für die Struktur gedacht.

Die Kopplung zwischen dem Kontext und den Strategien ist enger als die Kopplung zwischen der Abstraktion und der Implementierung im Brückenmuster.

Soweit ich weiß, verwenden Sie das Strategiemuster, wenn Sie Verhalten abstrahieren, das von einer externen Quelle bereitgestellt werden könnte (z. B. config könnte angeben, dass eine Plugin-Assembly geladen werden soll), und Sie verwenden das Bridge-Muster, wenn Sie es verwenden die gleichen Konstrukte, um Ihren Code ein bisschen ordentlicher zu machen. Der eigentliche Code sieht sehr ähnlich aus - Sie wenden die Muster nur aus etwas anderen Gründen an .


3
Ich kann also sagen, dass ich das Strategiemuster verwende, um das Verhalten abstrahieren zu können und gleichzeitig den Code ordentlicher wie im Brückenmuster aussehen zu lassen. Oder ich verwende das Brückenmuster, um den Code ordentlicher zu machen, und auch, weil es mir erlaubt Verhalten wie im Strategiemuster zu abstrahieren? und würde ich recht haben?
user20358

1
Der Unterschied zwischen den beiden liegt nur in ihrer Absicht. Ich denke also, wir können mit Sicherheit sagen, dass die beiden Muster funktional gleich sind, da beide dieselbe Idee verwenden und dieselbe Flexibilität bieten.
Elz

3
Die UML von Bridge ist in meiner Ausgabe des GoF-Buches ganz anders . Dieses Tool kann Bridge von Strategy unterscheiden.
Fuhrmanator

1
Wikipedia ist oft eine schreckliche Referenz. Zu Recht wurde diese Fehlinformation von der Seite entfernt. en.wikipedia.org/w/…
Fuhrmanator

2
Ich verstehe, dass dieselbe Technik verwendet wird, um eine Implementierung (Strategie) oder eine Schnittstelle (Bridge) zu abstrahieren. Strategie tauscht Verhalten aus, Bridge tauscht Schnittstellen aus (dies ermöglicht letztendlich den Austausch von Implementierungen mit solchen Schnittstellen). Mit anderen Worten, Bridge erstellt auf der einen Seite eine standardisierte Schnittstelle und steckt auf der anderen Seite Implementierungen mit unterschiedlichen Schnittstellen ein.
Nikaas

55

Das Brückenmuster ist ein Strukturmuster (WIE BAUEN SIE EINE SOFTWAREKOMPONENTE?). Das Strategiemuster ist ein dynamisches Muster (WIE MÖCHTEN SIE EIN VERHALTEN IN SOFTWARE AUSFÜHREN?).

Die Syntax ist ähnlich, aber die Ziele sind unterschiedlich:

  • Strategie : Sie haben mehr Möglichkeiten, eine Operation durchzuführen. Mit der Strategie können Sie den Algorithmus zur Laufzeit auswählen und eine einzelne Strategie ohne viele Nebenwirkungen zur Kompilierungszeit ändern.
  • Bridge : Sie können die Hierarchie von Schnittstelle und Klasse aufteilen und mit einer abstrakten Referenz verknüpfen (siehe Erläuterung ).

3
Wenn also die Syntax ähnlich ist, würde ich zu Recht sagen, dass ich eines dieser Muster verwende, um ein Softwareverhalten auf eine bestimmte Weise auszuführen, und auch, weil ich die Komponente auf diese Weise erstellen möchte, damit sie auch ordentlich aussieht?
user20358

11

Strategie:

  • Mit der Strategie verbundener Kontext: Die Kontextklasse (möglicherweise abstrakt, aber nicht wirklich eine Schnittstelle! Da Sie ein bestimmtes Verhalten und nicht die gesamte Implementierung kapseln möchten) würde die Strategie-Schnittstellenreferenz und die Implementierung kennen / enthalten , auf die das Strategieverhalten aufgerufen werden soll es.
  • Absicht ist die Fähigkeit, das Verhalten zur Laufzeit auszutauschen

    class Context {
    
         IStrategy strategyReference;
    
         void strategicBehaviour() {
    
            strategyReference.behave();
         }
    
    }
    

Brücke

  • Abstraktion nicht an die Implementierung gebunden: Die Abstraktionsschnittstelle (oder die abstrakte Klasse mit dem größten Teil des abstrakten Verhaltens) würde die Referenz der Implementierungsschnittstelle nicht kennen / enthalten
  • Es ist beabsichtigt, die Abstraktion vollständig von der Implementierung zu entkoppeln

    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();
    
          }
    
          .............
    
    }
    

10

Ich dachte das Gleiche, aber kürzlich musste ich Bridge verwenden und erkannte, dass Bridge Strategie verwendet und dem Kontext Abstraktion hinzufügt, damit Sie später weitere Änderungen vornehmen können, ohne den Client zu ändern. Bei Verwendung von Strategy ohne Abstraktion ist das Design nicht so flexibel und erfordert möglicherweise später Änderungen am Client. Bei Verwendung der gesamten Brücke wird das Design jedoch noch flexibler. Hier können Sie sehen, wie der Wechsel von der Strategie zur Brücke mehr Flexibilität bietet. Wir gehen auch davon aus, dass "Visum" und "Master" jetzt nicht nur auf Karten, sondern auch auf Telefonen und Chips verfügbar sind. und wenn wir Bridge verwenden, ist es viel einfacher, diese Unterstützung hinzuzufügen.

Strategie VS Bridge


9

Brücke : (Ein Strukturmuster)

Das Brückenmuster entkoppelt Abstraktion und Implementierung und ermöglicht es beiden, unabhängig voneinander zu variieren.

Verwenden Sie dieses Muster, wenn:

  1. Abstraktionen und Implementierungen wurden zum Zeitpunkt der Kompilierung noch nicht festgelegt
  2. Abstraktionen und Implementierungen sollten unabhängig voneinander geändert werden
  3. Änderungen in der Implementierung der Abstraktion sollten sich nicht auf die Aufruferanwendung auswirken
  4. Der Client sollte von den Implementierungsdetails isoliert sein.

Strategie: (Verhaltensmuster)

Mithilfe von Strategiemustern können Sie zur Laufzeit zwischen mehreren Algorithmen aus einer Familie von Algorithmen wechseln.

Verwenden Sie das Strategiemuster, wenn:

  1. Es sind mehrere Versionen von Algorithmen erforderlich
  2. Das Verhalten der Klasse muss zur Laufzeit dynamisch geändert werden
  3. Vermeiden Sie bedingte Anweisungen

Zusammenhängende Posts:

Wann verwenden Sie das Brückenmuster? Wie unterscheidet es sich vom Adaptermuster?

Beispiel aus der Praxis für das Strategiemuster


4

Entwurfsmustertypen

  • Verhalten: Muster charakterisieren die Art und Weise, wie Klassen oder Objekte interagieren und Verantwortung verteilen
  • Strukturell: Muster befassen sich mit der Zusammensetzung von Klassen oder Objekten.
  • Kreativ: Muster sind besorgt über den Prozess der Objekterstellung.

Brücke (strukturell)

Entkoppeln Sie eine Abstraktion von ihrer Implementierung, sodass jede davon variieren kann. unabhängig. Geben Sie hier die Bildbeschreibung ein

Nehmen Sie eine Fernbedienung. Die Fernbedienung verfügt über die Tasten 1-6. Dies ist die konkrete Klasse im obigen Diagramm. Jede Taste funktioniert anders, je nachdem, ob die Fernbedienung für einen Fernseher oder eine DVD verwendet wird. Die Funktionalität für jede Schaltfläche wird von der Implementierungsschnittstelle von der Implementierung abstrahiert.

Auf diese Weise können wir die Funktionsweise der Fernbedienung für jedes Gerät ändern.

Strategie (Verhalten)

Definieren Sie eine Familie von Algorithmen, kapseln Sie jeden einzelnen und machen Sie sie austauschbar. Geben Sie hier die Bildbeschreibung ein

In der Strategie, wenn wir das entfernte Szenario betrachten. Der "Status" ist die gesamte Fernbedienung, die wir durch Ändern der Statusreferenz des Kontexts austauschen. Die "creteStateA "(TV-Fernbedienung) "creteStateB" (DVD-Fernbedienung).

Zusätzliche Lektüre:


3
  1. Das Strategiemuster wird für Verhaltensentscheidungen verwendet, während das Brückenmuster für strukturelle Entscheidungen verwendet wird.

  2. Brigde Pattern trennt die abstrakten Elemente von den Implementierungsdetails, während Strategy Pattern darum geht, Algorithmen austauschbarer zu machen.

Strategiemuster in UML

Brigdenmuster in UML

Strategiemuster in 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")

Brigdenmuster in 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()

Wie kommt es, dass nur Strategiemuster "austauschbarer" sind? Da wir Code - Schnittstelle, nicht bis zur Umsetzung, können wir die Implementierungen in den Bereichen Strategie, oder Brücke tauschen, wie Sie in Ihrem Codebeispiel demonstriert, Austausch Stereomit TVund der Code funktioniert einfach.
denis631

2

Wenn Sie die Antwort von willcodejavaforfood hinzufügen, können sie in der Implementierung identisch sein. Sie verwenden jedoch eine Strategie, um Strategien wie die Sortierstrategie auszutauschen, während Sie Bridge verwenden, um die Implementierungen von zwei Objekten, z. B. einem Datenbank-Wrapper, und einem Netzwerkadapter zu überbrücken, sodass der Client-Code entweder mit derselben API arbeiten kann. Die Benennung sagt also eigentlich alles


1

Aus dem Wiki auf Strategiemuster

Das UML-Klassendiagramm für das Strategiemuster entspricht dem Diagramm für das Bridge-Muster. Diese beiden Entwurfsmuster sind jedoch in ihrer Absicht nicht gleich. Während das Strategiemuster für das Verhalten gedacht ist, ist das Brückenmuster für die Struktur gedacht.

Die Kopplung zwischen dem Kontext und den Strategien ist enger als die Kopplung zwischen der Abstraktion und der Implementierung im Brückenmuster.


Könnten Sie den letzten Satz näher erläutern?
gstackoverflow

1

Nur um das zu ergänzen, was bereits über den Mustervergleich gesagt wurde (Unterschied der Absicht, ...): Das Bridge-Muster ist auch absichtlich so strukturiert, dass die Seite der Abstraktionshierarchie variieren kann. In Sprachen wie C # könnte dies bedeuten, dass Sie über eine Abstraktionsbasis verfügen, die virtuelle Methoden enthält, um beabsichtigte Variationen zuzulassen, die für bestehende Verbraucher keine Probleme verursachen. Ansonsten könnten die beiden Muster größtenteils identisch erscheinen.


1

Das Strategiemuster wird verwendet, wenn Sie den Algorithmus oder die Strategie zur Laufzeit anschließen möchten. Als Kategorie des Musters bedeutet dies auch, dass es sich um das Verhalten der Objekte handelt. Andererseits ist Brücke ein Strukturmuster und befasst sich mit der Strukturhierarchie der Objekte. Es entkoppelt die Abstraktion von der Implementierung, indem es eine verfeinerte Abstraktion zwischen ihnen einführt. Eine verfeinerte Abstraktion kann mit der eingesteckten Laufzeitstrategie (In Strategy Pattern) verwechselt werden. Das Brückenmuster behandelt die strukturellen Aspekte, indem es einen Mechanismus bereitstellt, um zu vermeiden, dass n Klassen erstellt werden.


1

Für das Strategiemuster variiert nur die Implementierung.

Angenommen, Klasse A verwendet Klasse B, für die mehrere Implementierungen verfügbar sind. In diesem Fall wäre B also abstrakt, und die tatsächliche Implementierung würde zur Laufzeit bereitgestellt. Dies ist ein Strategiemuster

Nun, wenn A selbst abstrakt ist. Sowohl A als auch B können variieren. Sie würden das Brückenmuster verwenden.


0

Ich denke, es gibt einen kleinen Unterschied zwischen ihnen in dem Kontext, in dem sie verwendet werden.

Ich benutze das Brückenmuster, um orthogonale Konzepte zu trennen, die beide zu einem größeren gehören - damit sie unabhängig voneinander variieren können. Es handelt sich normalerweise um mehrere Abstraktionen.

IMO, das Strategiemuster ist einfacher oder flacher. Es dient OCP mit Sicherheit, muss aber nicht unbedingt Teil eines anderen und größeren Konzepts wie dem Bridge-Muster sein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.