Qual è la differenza tra il pattern bridge e il pattern strategico?


114

Ho provato a leggere molti articoli su dofactory , wikipedia e molti siti. Non ho idea delle differenze tra il modello del ponte e il modello della strategia.

So che entrambi disaccoppiano un'astrazione dalla sua implementazione e possono cambiare l'implementazione in fase di esecuzione.

Ma ancora non so in quale situazione dovrei usare la strategia o in quale situazione dovrei usare il bridge.

Risposte:


66

Semantica. Da wikipedia :

Il diagramma delle classi UML per il pattern Strategy è lo stesso del diagramma per il pattern Bridge. Tuttavia, questi due modelli di progettazione non sono gli stessi nel loro intento. Mentre il pattern Strategy è pensato per il comportamento, il pattern Bridge è pensato per la struttura.

L'accoppiamento tra il contesto e le strategie è più stretto dell'accoppiamento tra l'astrazione e l'implementazione nel pattern Bridge.

A quanto ho capito, stai utilizzando il modello di strategia quando astratti il ​​comportamento che potrebbe essere fornito da una fonte esterna (ad es. Config potrebbe specificare di caricare un assembly di plug-in) e stai utilizzando il modello di bridge quando usi gli stessi costrutti per rendere il tuo codice un po 'più ordinato. Il codice effettivo sarà molto simile: stai solo applicando i modelli per motivi leggermente diversi .


3
quindi posso dire che sto usando il modello di strategia per essere in grado di astrarre il comportamento e allo stesso tempo rendere il codice più ordinato come nel modello di ponte .. oppure, sto usando il modello di ponte per rendere il codice più ordinato e anche perché mi permette astrarre un comportamento come nel modello strategico? e avrei ragione?
user20358

1
La differenza tra i due sta solo nel loro intento. Quindi immagino che si possa tranquillamente affermare che, poiché entrambi usano la stessa idea e offrono la stessa flessibilità, i due modelli sono funzionalmente uguali.
Elz

3
L'UML di Bridge è abbastanza diverso nella mia copia del libro GoF. Questo strumento è in grado di distinguere Bridge da Strategy.
Fuhrmanator

1
Wikipedia è spesso un pessimo riferimento. Giustamente, quella disinformazione è stata rimossa dalla pagina. en.wikipedia.org/w/…
Fuhrmanator

2
Il modo in cui ottengo è che la stessa tecnica viene utilizzata per astrarre un'implementazione (strategia) o per astrarre un'interfaccia (bridge). Comportamenti di scambio di strategia, interfacce di scambio di bridge (questo alla fine consente di scambiare implementazioni con tali interfacce). In altre parole Bridge crea un'interfaccia standardizzata da un lato e collega le implementazioni con interfacce differenti dall'altro.
Nikaas

55

Il modello Bridge è un modello strutturale (COME SI COSTRUISCE UN COMPONENTE SOFTWARE?). Il pattern Strategy è un pattern dinamico (COME VUOI ESEGUIRE UN COMPORTAMENTO NEL SOFTWARE?).

La sintassi è simile ma gli obiettivi sono diversi:

  • Strategia : hai più modi per eseguire un'operazione; con la strategia, puoi scegliere l'algoritmo in fase di esecuzione e puoi modificare una singola strategia senza molti effetti collaterali in fase di compilazione;
  • Bridge : puoi dividere la gerarchia di interfaccia e classe, unendola con un riferimento astratto (vedi spiegazione )

3
quindi, se la sintassi è simile, sarei corretto nel dire che sto usando uno di questi modelli per eseguire un comportamento del software in un modo particolare e anche perché voglio costruire il componente in quel modo in modo che appaia pulito?
user20358

11

Strategia:

  • Contesto legato alla strategia: la classe del contesto (possibilmente astratta ma non proprio un'interfaccia! Poiché si desidera incapsulare un comportamento specifico e non l'intera implementazione) conoscerebbe / conterrebbe il riferimento all'interfaccia della strategia e l' implementazione per invocare il comportamento della strategia esso.
  • L'intento è la capacità di scambiare il comportamento in fase di esecuzione

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

ponte

  • Astrazione non legata all'implementazione: l'interfaccia di astrazione (o la classe astratta con la maggior parte del comportamento astratto) non conoscerebbe / conterrebbe il riferimento all'interfaccia di implementazione
  • L'intento è disaccoppiare completamente l'astrazione dall'implementazione

    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

Stavo pensando la stessa cosa, ma recentemente ho dovuto usare il bridge e ho capito che il bridge utilizza la strategia e aggiunge astrazione al contesto in modo che in seguito tu possa apportare più modifiche senza cambiare il client. Quando si utilizza la strategia senza l'astrazione, il design non è così flessibile e potrebbe richiedere modifiche al client in un secondo momento. Ma quando si utilizza l'intero ponte, il design diventa ancora più flessibile. Qui puoi vedere come passare da Strategy a Bridge offra maggiore flessibilità. Inoltre assumiamo che ora "visa" e "master" non siano disponibili solo su carte ma anche su telefoni e chip; e se usiamo il bridge è molto più facile aggiungere quel supporto.

Strategia VS Bridge


9

Ponte : (un modello strutturale)

Il pattern bridge disaccoppia l'astrazione e l'implementazione e consente a entrambe di variare indipendentemente.

Usa questo modello quando:

  1. Le astrazioni e le implementazioni non sono state decise in fase di compilazione
  2. Le astrazioni e le implementazioni dovrebbero essere modificate in modo indipendente
  3. Le modifiche all'implementazione dell'astrazione non dovrebbero influire sull'applicazione del chiamante
  4. Il cliente dovrebbe essere isolato dai dettagli di implementazione.

Strategia: (modello comportamentale)

I modelli di strategia consentono di passare da più algoritmi a una famiglia di algoritmi in fase di esecuzione.

Usa il modello di strategia quando:

  1. Sono necessarie più versioni di algoritmi
  2. Il comportamento della classe deve essere modificato dinamicamente in fase di esecuzione
  3. Evita le affermazioni condizionali

Post correlati:

Quando usi il Bridge Pattern? In cosa differisce dal pattern Adapter?

Esempio del mondo reale del modello di strategia


4

Tipi di pattern di design

  • Comportamentali: i modelli caratterizzano i modi in cui le classi o gli oggetti interagiscono e distribuiscono le responsabilità
  • Strutturale: i modelli si occupano della composizione di classi o oggetti.
  • Creazionale: i modelli si preoccupano del processo di creazione degli oggetti.

Bridge (strutturale)

Separare un'astrazione dalla sua implementazione in modo che ciascuna possa variare. indipendentemente. inserisci qui la descrizione dell'immagine

Prendi un telecomando. Il telecomando ha i pulsanti 1-6. Questa è la classe concreta nel diagramma sopra. Ciascun pulsante funzionerà in modo diverso a seconda che il telecomando venga utilizzato per una TV o un DVD. La funzionalità di ogni pulsante è astratta dall'implementazione dell'interfaccia dell'implementatore.

Questo ci permette di cambiare il modo in cui il telecomando funzionerà per ogni dispositivo.

Strategia (comportamentale)

Definisci una famiglia di algoritmi, incapsulali ciascuno e rendili intercambiabili. inserisci qui la descrizione dell'immagine

In strategia, se stessimo guardando lo scenario remoto. Lo "stato" è l'intero telecomando che sostituiamo cambiando il riferimento allo stato del contesto. Il "concreteStateA" (telecomando TV) "concreteStateB" (telecomando DVD).

Letture aggiuntive:


3
  1. Il modello di strategia viene utilizzato per le decisioni comportamentali, mentre il modello di ponte viene utilizzato per le decisioni strutturali.

  2. Brigde Pattern separa gli elementi astratti dai dettagli di implementazione, mentre Strategy Pattern si occupa di rendere gli algoritmi più intercambiabili.

Modello di strategia in UML

Modello Brigde in UML

Schema strategico 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")

Modello Brigde 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()

come mai solo il pattern strategico è più "intercambiabile". Poiché codifichiamo per l'interfaccia, non per l'implementazione, possiamo scambiare le implementazioni in strategia o bridge, come hai dimostrato nell'esempio di codice, scambiando Stereocon TVe il codice funziona.
denis631

2

Aggiungendo alla risposta di willcodejavaforfood, possono essere gli stessi, nell'implementazione. Tuttavia si utilizza la strategia per scambiare strategie come la strategia di ordinamento, mentre si utilizza il bridge per collegare le implementazioni di due oggetti, ad esempio un wrapper di database e un adattatore di rete in modo che il codice client possa utilizzare entrambi lavorando contro la stessa API. Quindi la denominazione in realtà dice tutto


1

Dal wiki su Strategy pattern

Il diagramma delle classi UML per il pattern Strategy è lo stesso del diagramma per il pattern Bridge. Tuttavia, questi due modelli di progettazione non sono gli stessi nel loro intento. Mentre il pattern Strategy è pensato per il comportamento, il pattern Bridge è pensato per la struttura.

L'accoppiamento tra il contesto e le strategie è più stretto dell'accoppiamento tra l'astrazione e l'implementazione nel pattern Bridge.


Potresti elaborare l'ultima frase?
gstackoverflow

1

Giusto per aggiungere a quanto già detto sul confronto dei pattern (differenza di intenti, ...): anche il pattern Bridge è intenzionalmente strutturato per permettere al lato di astrazione della gerarchia di variare. In linguaggi come C # ciò potrebbe implicare che si dispone di una base di astrazione che contiene metodi virtuali per consentire variazioni intenzionali che non causano problemi ai consumatori esistenti. Diverso da quello che i due modelli potrebbero sembrare identici per la maggior parte.


1

Il modello di strategia viene utilizzato quando si desidera collegare un algoritmo o una strategia in fase di esecuzione. Poiché la categoria di pattern implica anche che si tratti del comportamento degli oggetti. D'altra parte il bridge è un modello strutturale e si occupa della gerarchia strutturale degli oggetti. Disaccoppia l'astrazione dall'implementazione introducendo un'astrazione raffinata tra di loro. L'astrazione raffinata può essere confusa con la strategia di runtime collegata (modello In Strategy). Bridge pattern si occupa degli aspetti strutturali fornendo un meccanismo per evitare di creare n numero di classi.


1

Per il modello di strategia varia solo l'implementazione.

Supponiamo che la classe A utilizzi la classe B che ha più implementazioni disponibili. Quindi in quel caso B sarebbe astratto con l'implementazione effettiva fornita in fase di esecuzione. Questo è il modello strategico

Ora, se A stesso è astratto. Sia A che B possono variare. Useresti il ​​pattern Bridge.


0

Penso che ci sia una leggera differenza tra loro nel contesto in cui vengono utilizzati.

Uso il modello Bridge per separare concetti ortogonali che appartengono entrambi a uno più grande - per lasciarli variare indipendentemente. Di solito coinvolge più astrazioni.

IMO, il modello di strategia è più semplice o più piatto. Sicuramente serve all'OCP, ma non deve necessariamente far parte di un altro concetto più ampio come il modello Bridge.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.