Pregunta

Traté de leer muchos artículos en dofactory , wikipedia y muchos sitios. No tengo idea de las diferencias entre el patrón de puente y el patrón de estrategia.

Sé que ambos desacoplan una abstracción de su implementación y pueden cambiar la implementación en tiempo de ejecución.

Pero todavía no sé en qué situación debería usar la estrategia o en qué situación debería usar el puente.

¿Fue útil?

Solución

Semántica. De wikipedia :

  

El diagrama de clase UML para la estrategia   patrón es el mismo que el diagrama para   El patrón del puente. Sin embargo, estos dos   los patrones de diseño no son iguales en   su intención Mientras la estrategia   El patrón es para el comportamiento, el   El patrón del puente está destinado a la estructura.

     

El acoplamiento entre el contexto y   las estrategias son más estrictas que las   acoplamiento entre la abstracción y   la implementación en el puente   patrón.

Según tengo entendido, está utilizando el patrón de estrategia cuando abstrae el comportamiento que podría proporcionarse desde una fuente externa (p. ej., la configuración podría especificar cargar algún ensamblaje de complemento), y está utilizando el patrón de puente cuando usas las mismas construcciones para hacer tu código un poco más ordenado El código real se verá muy similar: solo está aplicando los patrones por razones ligeramente diferentes .

Otros consejos

El patrón Bridge es un patrón estructural (¿CÓMO CONSTRUYE UN COMPONENTE DE SOFTWARE?). El patrón de estrategia es un patrón dinámico (¿CÓMO DESEA EJECUTAR UN COMPORTAMIENTO EN EL SOFTWARE?).

La sintaxis es similar pero los objetivos son diferentes:

  • Estrategia : tiene más formas de realizar una operación; con la estrategia, puede elegir el algoritmo en tiempo de ejecución y puede modificar una sola estrategia sin muchos efectos secundarios en tiempo de compilación;
  • Puente : puede dividir la jerarquía de la interfaz y la clase, unirla con una referencia abstracta (consulte explicación )

Estrategia :

  • Contexto vinculado a la estrategia: la clase de contexto (¡posiblemente abstracta pero no realmente una interfaz! ya que desea encapsular un comportamiento específico y no toda la implementación) conocería / contendría la referencia de interfaz de estrategia y la implementación para invocar el comportamiento de la estrategia en él.
  • La intención es la capacidad de intercambiar el comportamiento en tiempo de ejecución

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

Bridge

  • Abstracción no vinculada a la Implementación: La interfaz de abstracción (o clase abstracta con la mayoría del resumen de comportamiento) no conocería / contendría la referencia de interfaz de implementación
  • La intención es desacoplar completamente la abstracción de la implementación

    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 : (Un patrón estructural)

El patrón de puente desacopla la abstracción y la implementación y permite que ambos varíen independientemente.

Use este patrón cuando:

  1. Las abstracciones e implementaciones no se han decidido en tiempo de compilación
  2. Las abstracciones y las implementaciones deben cambiarse independientemente
  3. Los cambios en la implementación de la abstracción no deberían afectar la aplicación de la persona que llama
  4. El cliente debe estar aislado de los detalles de implementación.

Estrategia : (Patrón de comportamiento)

Los patrones de estrategia le permiten cambiar entre múltiples algoritmos de una familia de algoritmos en tiempo de ejecución.

Usar patrón de estrategia cuando:

  1. Se requieren múltiples versiones de algoritmos
  2. El comportamiento de la clase debe cambiarse dinámicamente en tiempo de ejecución
  3. Evitar declaraciones condicionales

Publicaciones relacionadas:

¿Cuándo utiliza el patrón de puente? ¿En qué se diferencia del patrón del adaptador?

Ejemplo del mundo real del patrón de estrategia

Estaba pensando lo mismo, pero recientemente tuve que usar bridge y me di cuenta de que bridge está usando una estrategia y agregando abstracción al contexto para que luego puedas hacer más cambios sin cambiar el cliente. Cuando se utiliza la Estrategia sin la abstracción, el diseño no es tan flexible y puede requerir cambios en el cliente más adelante. Pero cuando se usa todo el puente, el diseño se vuelve aún más flexible. Aquí puede ver cómo pasar de Estrategia a Puente brinda más flexibilidad. También suponemos que ahora " visa " y "maestro" no solo están disponibles en tarjetas sino también en teléfonos y chips; y si usamos bridge es mucho más fácil agregar ese soporte.

 Estrategia VS Bridge

Tipos de patrones de diseño

  • Comportamiento: los patrones caracterizan las formas en que las clases u objetos interactúan y distribuyen la responsabilidad
  • Los patrones
  • Estructurales: tratan con la composición de clases u objetos.
  • Creacional: los patrones están preocupados por el proceso de creación de objetos.

Puente (Estructural)

  

Desacoplar una abstracción de su implementación para que cada una pueda variar.   independientemente.    ingrese la descripción de la imagen aquí

Toma un control remoto. El control remoto tiene botones 1-6. Esta es la clase concreta en el diagrama de arriba. Cada botón funcionará de manera diferente dependiendo de si el control remoto se usa para un televisor o DVD. La funcionalidad de cada botón se abstrae de la implementación mediante la interfaz del implementador.

Esto nos permite cambiar cómo funcionará el control remoto para cada dispositivo.

Estrategia (Comportamiento)

  

Defina una familia de algoritmos, encapsule cada uno y hágalos intercambiables.    ingrese la descripción de la imagen aquí

En estrategia, si estuviéramos mirando el escenario remoto. El "estado" es todo el control remoto que intercambiamos cambiando la referencia de estado del contexto. El `` concreteStateA '' (Control remoto de TV) " concreteStateB " (DVD remoto).

Lectura adicional:

Agregando a la respuesta de willcodejavaforfood, pueden ser lo mismo, en la implementación. Sin embargo, usa la estrategia para intercambiar estrategias, como la estrategia de clasificación, mientras usa el puente para unir las implementaciones de dos objetos, por ejemplo, un contenedor de base de datos y un adaptador de red, de modo que el código del cliente pueda usarlo en la misma API. Entonces, la denominación lo dice todo

  1. Estrategia El patrón se usa para decisiones de comportamiento, mientras que el Puente se usa para decisiones estructurales.

  2. Brigde Pattern separa los elementos abstractos de los detalles de implementación, mientras que Strategy Pattern se refiere a hacer que los algoritmos sean más intercambiables.

Patrón de estrategia en UML

Patrón Brigde en UML

Patrón de estrategia en 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")

Patrón Brigde en 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()

De la wiki en Patrón de estrategia

  

El diagrama de clase UML para la estrategia   patrón es el mismo que el diagrama para   El patrón del puente. Sin embargo, estos dos   los patrones de diseño no son iguales en   su intención Mientras la estrategia   El patrón es para el comportamiento, el   El patrón del puente está destinado a la estructura.

     

El acoplamiento entre el contexto y   las estrategias son más estrictas que las   acoplamiento entre la abstracción y   la implementación en el puente   patrón.

Solo para agregar a lo que ya se ha dicho sobre la comparación de patrones (diferencia de intención, ...): el patrón de Puente también está estructurado intencionalmente para permitir que varíe el lado de la jerarquía de abstracción. En lenguajes como C #, esto podría implicar que tiene una base de abstracción que contiene métodos virtuales como una forma de permitir variaciones intencionadas que no causen problemas a los consumidores existentes. Aparte de eso, los dos patrones pueden parecer idénticos en su mayor parte.

El patrón de estrategia se utiliza cuando desea conectar un algoritmo o estrategia en tiempo de ejecución. Como categoría de patrón también implica que se trata del comportamiento de los objetos. Por otro lado, el puente es un patrón estructural y se ocupa de la jerarquía estructural de los objetos. Desacopla la abstracción de la implementación al introducir una abstracción refinada entre ellos. La abstracción refinada se puede confundir con la estrategia de tiempo de ejecución conectada (en el patrón de estrategia). El patrón de puente trata los aspectos estructurales al proporcionar un mecanismo para evitar crear n número de clases.

Para el patrón de estrategia solo varía la implementación.

Supongamos que la clase A está usando la clase B que tiene múltiples implementaciones disponibles. Entonces, en ese caso, B sería abstracto con la implementación real proporcionada en tiempo de ejecución. Este es el patrón de estrategia

Ahora si A en sí mismo es abstracto. Tanto A como B pueden variar. Usarías el patrón Puente.

Creo que hay una ligera diferencia entre ellos en el contexto en que se usan.

Utilizo el patrón Puente para separar los conceptos ortogonales que ambos pertenecen a uno más grande, para que puedan variar de forma independiente. Por lo general, involucra múltiples abstracciones.

OMI, el patrón de estrategia es más simple o más plano. Seguramente sirve a OCP, pero no necesariamente forma parte de otro concepto más grande como el patrón Bridge.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top