Jaka jest różnica między wzorcem mostu a wzorcem strategii?


114

Próbowałem przeczytać wiele artykułów na stronie dofactory , wikipedii i wielu witrynach. Nie mam pojęcia o różnicach między wzorcem mostu a wzorcem strategii.

Wiem, że oba oddzielają abstrakcję od implementacji i mogą zmieniać implementację w czasie wykonywania.

Ale nadal nie wiem, w jakiej sytuacji powinienem zastosować strategię lub w jakiej sytuacji powinienem użyć brydża.

Odpowiedzi:


66

Semantyka. Z Wikipedii :

Diagram klas UML dla wzorca Strategy jest taki sam, jak diagram dla wzorca Bridge. Jednak te dwa wzorce projektowe nie są takie same w zamierzeniu. Podczas gdy wzorzec strategii jest przeznaczony do zachowania, wzorzec mostka jest przeznaczony do struktury.

Połączenie między kontekstem a strategiami jest ściślejsze niż połączenie między abstrakcją a implementacją we wzorcu Bridge.

Jak rozumiem, używasz wzorca strategii, gdy wyodrębniasz zachowanie, które może być dostarczone z zewnętrznego źródła (np. Config może określać ładowanie zestawu wtyczki) i używasz wzorca mostu, gdy używasz te same konstrukcje, aby Twój kod był nieco schludniejszy. Rzeczywisty kod będzie wyglądał bardzo podobnie - po prostu stosujesz wzorce z nieco innych powodów .


3
więc mogę powiedzieć, że używam wzorca strategii, aby móc abstrakcyjnie zachowywać się, jednocześnie sprawiając, że kod wygląda ładniej, jak we wzorcu mostu .. lub używam wzorca Bridge, aby uczynić kod bardziej uporządkowanym, a także dlatego, że pozwala mi do abstrakcyjnego zachowania, jak we wzorcu strategii? i czy miałbym rację?
user20358

1
Różnica między nimi tkwi tylko w ich zamiarze. Więc myślę, że możemy śmiało powiedzieć, że ponieważ obaj używają tego samego pomysłu i oferują taką samą elastyczność, oba wzorce są funkcjonalnie takie same.
Elz

3
UML firmy Bridge jest zupełnie inny w mojej kopii książki GoF. To narzędzie jest w stanie odróżnić Bridge od strategii.
Fuhrmanator

1
Wikipedia jest często okropnym źródłem informacji. Słusznie, ta dezinformacja została usunięta ze strony. en.wikipedia.org/w/…
Fuhrmanator

2
Sposób, w jaki to rozumiem, polega na tym, że ta sama technika jest używana do abstrakcji (strategii) lub interfejsu (mostu). Zachowania dotyczące zamiany strategii, interfejsy zamiany mostków (ostatecznie umożliwia to zamianę implementacji z takimi interfejsami). Innymi słowy, Bridge tworzy z jednej strony znormalizowany interfejs, a z drugiej podłącza implementacje z różnymi interfejsami.
Nikaas

55

Wzorzec Bridge jest wzorem strukturalnym (JAK BUDOWAĆ ELEMENT OPROGRAMOWANIA?). Wzorzec Strategii jest wzorcem dynamicznym (JAK CHCESZ PROWADZIĆ ZACHOWANIE W OPROGRAMOWANIU?).

Składnia jest podobna, ale cele są różne:

  • Strategia : masz więcej sposobów na wykonanie operacji; ze strategią, możesz wybrać algorytm w czasie wykonywania i możesz modyfikować pojedynczą strategię bez wielu skutków ubocznych w czasie kompilacji;
  • Bridge : możesz podzielić hierarchię interfejsu i klasy, połączyć ją z abstrakcyjnym odniesieniem (patrz wyjaśnienie )

3
więc jeśli składnia jest podobna, czy miałbym rację mówiąc, że używam jednego z tych wzorców do uruchamiania zachowania oprogramowania w określony sposób, a także dlatego, że chcę zbudować komponent w ten sposób, aby również wyglądał schludnie?
user20358

11

Strategia:

  • Kontekst powiązany ze strategią: Klasa kontekstu (prawdopodobnie abstrakcyjna, ale nie w rzeczywistości interfejs! Ponieważ chcesz ująć określone zachowanie, a nie całą implementację), znałaby / zawierała odniesienie do interfejsu strategii i implementację wywołującą zachowanie strategii to.
  • Intencja to możliwość zamiany zachowań w czasie wykonywania

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

Most

  • Abstrakcja niezwiązana z implementacją: interfejs abstrakcji (lub klasa abstrakcyjna z większością abstrakcyjnych zachowań) nie zna / nie zawiera odwołania do interfejsu implementacji
  • Intencją jest całkowite oddzielenie abstrakcji od implementacji

    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

Myślałem o tym samym, ale ostatnio musiałem użyć mostu i zdałem sobie sprawę, że most używa strategii i dodaje abstrakcję do kontekstu, aby później można było wprowadzić więcej zmian bez zmiany klienta. Podczas korzystania ze strategii bez abstrakcji projekt nie jest tak elastyczny i może wymagać późniejszych zmian po stronie klienta. Ale przy zastosowaniu całego mostu konstrukcja staje się jeszcze bardziej elastyczna. Tutaj możesz zobaczyć, jak przejście od strategii do mostu zapewnia większą elastyczność. Zakładamy również, że teraz „visa” i „master” są dostępne nie tylko na kartach, ale także w telefonach i chipach; a jeśli użyjemy mostka, znacznie łatwiej będzie dodać to wsparcie.

Strategia VS Bridge


9

Mostek : (wzór strukturalny)

Wzorzec mostu oddziela abstrakcję od implementacji i umożliwia niezależną zmianę obu.

Użyj tego wzorca, gdy:

  1. Abstrakcje i implementacje nie zostały określone w czasie kompilacji
  2. Abstrakcje i implementacje powinny być zmieniane niezależnie
  3. Zmiany w implementacji abstrakcji nie powinny wpływać na aplikację wywołującą
  4. Klient powinien być odizolowany od szczegółów realizacji.

Strategia: (wzorzec behawioralny)

Wzorce strategii umożliwiają przełączanie się między wieloma algorytmami z rodziny algorytmów w czasie wykonywania.

Użyj wzorca strategii, gdy:

  1. Wymaganych jest wiele wersji algorytmów
  2. Zachowanie klasy należy zmieniać dynamicznie w czasie wykonywania
  3. Unikaj instrukcji warunkowych

Powiązane posty:

Kiedy używasz wzoru mostka? Czym różni się od wzoru adaptera?

Przykład wzorca strategii ze świata rzeczywistego


4

Typy wzorów projektowych

  • Behawioralne: wzorce charakteryzują sposoby, w jakie klasy lub obiekty oddziałują na siebie i rozdzielają odpowiedzialność
  • Strukturalne: wzorce dotyczą kompozycji klas lub obiektów.
  • Kreacyjny: wzorce dotyczą procesu tworzenia obiektów.

Most (konstrukcyjny)

Oddziel abstrakcję od jej implementacji, aby każda mogła się różnić. niezależnie. wprowadź opis obrazu tutaj

Weź pilota. Pilot posiada przyciski 1-6. To jest konkretna klasa na powyższym diagramie. Każdy przycisk będzie działał inaczej w zależności od tego, czy pilot jest używany do telewizora, czy do odtwarzacza DVD. Funkcjonalność każdego przycisku jest wyodrębniona z implementacji przez interfejs implementatora.

Dzięki temu możemy zmienić sposób działania pilota na każdym urządzeniu.

Strategia (behawioralna)

Zdefiniuj rodzinę algorytmów, hermetyzuj każdy z nich i uczyń je wymiennymi. wprowadź opis obrazu tutaj

W strategii, gdybyśmy patrzyli na scenariusz zdalny. „Stan” to cały pilot, który wymieniamy, zmieniając odniesienie do stanu kontekstu. „ConcreteStateA” (pilot do telewizora) „concreteStateB” (pilot DVD).

Dodatkowe lektury:


3
  1. Wzorzec strategii jest używany do decyzji behawioralnych, a wzorzec mostu do decyzji strukturalnych.

  2. Brigde Pattern oddziela abstrakcyjne elementy od szczegółów implementacji, podczas gdy Strategy Pattern zajmuje się zwiększeniem wymienności algorytmów.

Wzorzec strategii w UML

Wzorzec Brigde w UML

Wzorzec strategii w 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")

Wzór Brigde w 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()

dlaczego tylko wzorzec strategii jest bardziej „wymienny”. Ponieważ kodujemy do interfejsu, a nie do implementacji, możemy zamienić implementacje w strategii lub pomostować, jak zademonstrowałeś w swoim przykładzie kodu, zamiana Stereoz TVi kod po prostu działa.
denis631

2

Dodając do odpowiedzi willcodejavaforfood, mogą one być takie same w realizacji. Jednak strategia jest używana do zamiany strategii, takich jak strategia sortowania, podczas gdy mostek służy do łączenia implementacji dwóch obiektów, powiedzmy opakowania bazy danych i karty sieciowej, aby kod klienta mógł używać jednego z tych samych funkcji API. Więc nazewnictwo mówi wszystko


1

Z wiki o wzorcu strategii

Diagram klas UML dla wzorca Strategy jest taki sam, jak diagram dla wzorca Bridge. Jednak te dwa wzorce projektowe nie są takie same w zamierzeniu. Podczas gdy wzorzec strategii jest przeznaczony do zachowania, wzorzec mostka jest przeznaczony do struktury.

Połączenie między kontekstem a strategiami jest ściślejsze niż połączenie między abstrakcją a implementacją we wzorcu Bridge.


Czy mógłbyś rozwinąć ostatnie zdanie?
gstackoverflow

1

Aby dodać do tego, co już zostało powiedziane na temat porównania wzorców (różnica intencji, ...): wzorzec Bridge jest również celowo skonstruowany, aby umożliwić zmianę strony hierarchii abstrakcji. W językach takich jak C # może to oznaczać, że masz bazę abstrakcji, która zawiera metody wirtualne jako sposób na dopuszczenie zamierzonych odmian, które nie powodują problemów dla istniejących konsumentów. Poza tym te dwa wzory mogą w większości wyglądać identycznie.


1

Wzorzec strategii jest używany, gdy chcesz podłączyć algorytm lub strategię w czasie wykonywania. Jako kategoria wzorca oznacza również, że zajmuje się zachowaniem obiektów. Z drugiej strony most jest wzorem strukturalnym i dotyczy strukturalnej hierarchii obiektów. Oddziela abstrakcję od implementacji, wprowadzając między nimi wyrafinowaną abstrakcję. Dopracowaną abstrakcję można pomylić z włączoną strategią czasu wykonywania (wzorzec In Strategy). Wzorzec mostu zajmuje się aspektami strukturalnymi, zapewniając mechanizm pozwalający uniknąć tworzenia n liczby klas.


1

W przypadku wzorca strategii zmienia się tylko realizacja.

Załóżmy, że klasa A używa klasy B, która ma wiele dostępnych implementacji. W takim przypadku B byłby abstrakcyjny z rzeczywistą implementacją dostarczoną w czasie wykonywania. To jest wzorzec strategii

Otóż, jeśli sam A jest abstrakcyjny. Zarówno A, jak i B mogą się różnić. Możesz użyć wzorca mostka.


0

Myślę, że jest między nimi niewielka różnica w kontekście, w jakim są używane.

Używam wzorca Bridge, aby oddzielić pojęcia ortogonalne, z których oba należą do większego - aby umożliwić im niezależne zmiany. Zwykle obejmuje wiele abstrakcji.

IMO, wzorzec strategii jest prostszy lub bardziej płaski. Z pewnością służy OCP, ale niekoniecznie musi być częścią innej i większej koncepcji, takiej jak wzorzec Bridge.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.