diff --git a/README.md b/README.md index 2d67955..37cb0ed 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ Un **Proxy** o sustituto: * Usar un nivel extra de indirección para permitir el acceso distribuido, controlado e inteligente. * Agregar un *"wrapper"* para proteger el componente real de la complejidad innecesaria. Este *wrapper* permite agregar funcionalidad al objeto de interés sin cambiar el código del objeto. -Aunque tenga similitudes al patrón Facade, ambos son diferentes. +Aunque a simple vista tenga similitudes al patrón Facade, ambos tiene matices diferentes. * Mientras que los objetos Proxy representan a un objeto, los objetos Facade representan a un subsistema de objetos. * Un objeto cliente Proxy no puede acceder a un objeto interno directamente, mientras que Facade no lo impide. * Un objeto Proxy provee control de acceso a un único objeto de interés. Sin embargo, un objeto Facade provee una interface de alto nivel a un subsistema de objetos. @@ -308,3 +308,23 @@ En algunos casos los recursos pueden ser limitados por lo que se especifica un n * *Share resources*: Diferentes clientes necesitarán el mismo recurso en diferentes momentos. **Referencia:** [https://www.javatpoint.com/object-pool-pattern](https://www.javatpoint.com/object-pool-pattern) + +## Bridge [↑](#lista-de-patrones) + +**Propósito:** Permite desacoplar una abstracción de su implementación, de manera que ambas puedan ser modificadas independientemente sin necesidad de alterar por ello la otra. + +**Aplicación:** Usamos el patrón [Bridge](https://github.com/peterm85/design-patterns/tree/master/src/bridge/pattern) cuando... +* Se desea evitar un enlace permanente entre la abstracción y su implementación. Esto puede ser debido a que la implementación debe ser seleccionada o cambiada en tiempo de ejecución. +* Tanto las abstracciones como sus implementaciones deben ser extensibles por medio de subclases. En este caso, el patrón Bridge permite combinar abstracciones e implementaciones diferentes y extenderlas independientemente. +* Cambios en la implementación de una abstracción no deben impactar en los clientes, es decir, su código no debe tener que ser recompilado. +* Se desea compartir una implementación entre múltiples objetos (quizá usando contadores), y este hecho debe ser escondido a los clientes. + +**Usos típicos:** +* *Desacoplar* interfaz e implementación. +* Mejorar la *extensibilidad*. +* Esconder los detalles de la implementación a los clientes. + +**Ejemplos:** +* [Taller](https://github.com/peterm85/design-patterns/tree/master/src/bridge/examples/workshop) + +**Referencia:** [https://www.geeksforgeeks.org/bridge-design-pattern/](https://www.geeksforgeeks.org/bridge-design-pattern/) diff --git a/src/bridge/examples/workshop/Assemble.java b/src/bridge/examples/workshop/Assemble.java new file mode 100644 index 0000000..efcf116 --- /dev/null +++ b/src/bridge/examples/workshop/Assemble.java @@ -0,0 +1,10 @@ +package bridge.examples.workshop; + +public class Assemble implements Workshop { + + @Override + public void work() { + System.out.print(" And"); + System.out.println(" Assembled."); + } +} \ No newline at end of file diff --git a/src/bridge/examples/workshop/Bike.java b/src/bridge/examples/workshop/Bike.java new file mode 100644 index 0000000..dd9e85a --- /dev/null +++ b/src/bridge/examples/workshop/Bike.java @@ -0,0 +1,15 @@ +package bridge.examples.workshop; + +public class Bike extends Vehicle { + + public Bike(Workshop workShop1, Workshop workShop2) { + super(workShop1, workShop2); + } + + @Override + public void manufacture() { + System.out.print("Bike "); + workShop1.work(); + workShop2.work(); + } +} diff --git a/src/bridge/examples/workshop/Car.java b/src/bridge/examples/workshop/Car.java new file mode 100644 index 0000000..d776427 --- /dev/null +++ b/src/bridge/examples/workshop/Car.java @@ -0,0 +1,15 @@ +package bridge.examples.workshop; + +public class Car extends Vehicle { + + public Car(Workshop workShop1, Workshop workShop2){ + super(workShop1, workShop2); + } + + @Override + public void manufacture() { + System.out.print("Car "); + workShop1.work(); + workShop2.work(); + } +} diff --git a/src/bridge/examples/workshop/Client.java b/src/bridge/examples/workshop/Client.java new file mode 100644 index 0000000..d38d778 --- /dev/null +++ b/src/bridge/examples/workshop/Client.java @@ -0,0 +1,11 @@ +package bridge.examples.workshop; + +public class Client { + + public static void main(String[] args) { + Vehicle vehicle1 = new Car(new Produce(), new Assemble()); + vehicle1.manufacture(); + Vehicle vehicle2 = new Bike(new Produce(), new Assemble()); + vehicle2.manufacture(); + } +} diff --git a/src/bridge/examples/workshop/Produce.java b/src/bridge/examples/workshop/Produce.java new file mode 100644 index 0000000..b896c41 --- /dev/null +++ b/src/bridge/examples/workshop/Produce.java @@ -0,0 +1,9 @@ +package bridge.examples.workshop; + +public class Produce implements Workshop { + + @Override + public void work() { + System.out.print("Produced"); + } +} diff --git a/src/bridge/examples/workshop/Vehicle.java b/src/bridge/examples/workshop/Vehicle.java new file mode 100644 index 0000000..57f9f9f --- /dev/null +++ b/src/bridge/examples/workshop/Vehicle.java @@ -0,0 +1,14 @@ +package bridge.examples.workshop; + +public abstract class Vehicle { + + protected Workshop workShop1; + protected Workshop workShop2; + + protected Vehicle(Workshop workShop1, Workshop workShop2) { + this.workShop1 = workShop1; + this.workShop2 = workShop2; + } + + abstract public void manufacture(); +} diff --git a/src/bridge/examples/workshop/Workshop.java b/src/bridge/examples/workshop/Workshop.java new file mode 100644 index 0000000..73fec1c --- /dev/null +++ b/src/bridge/examples/workshop/Workshop.java @@ -0,0 +1,5 @@ +package bridge.examples.workshop; + +public interface Workshop { + abstract public void work(); +} diff --git a/src/bridge/pattern/Abstraction.java b/src/bridge/pattern/Abstraction.java new file mode 100644 index 0000000..5d66159 --- /dev/null +++ b/src/bridge/pattern/Abstraction.java @@ -0,0 +1,5 @@ +package bridge.pattern; + +public interface Abstraction { + void operacion(); +} diff --git a/src/bridge/pattern/Client.java b/src/bridge/pattern/Client.java new file mode 100644 index 0000000..c2d666a --- /dev/null +++ b/src/bridge/pattern/Client.java @@ -0,0 +1,15 @@ +package bridge.pattern; + +public class Client { + + public static void main(String[] args) { + + Abstraction[] abstracciones = new Abstraction[2]; + abstracciones[0] = new RefinedAbstraction(new ImplementorA()); + abstracciones[1] = new RefinedAbstraction(new ImplementorB()); + + for(Abstraction abstraccion:abstracciones) { + abstraccion.operacion(); + } + } +} diff --git a/src/bridge/pattern/Implementor.java b/src/bridge/pattern/Implementor.java new file mode 100644 index 0000000..bb294e4 --- /dev/null +++ b/src/bridge/pattern/Implementor.java @@ -0,0 +1,5 @@ +package bridge.pattern; + +public interface Implementor { + void operacion(); +} diff --git a/src/bridge/pattern/ImplementorA.java b/src/bridge/pattern/ImplementorA.java new file mode 100644 index 0000000..435e60e --- /dev/null +++ b/src/bridge/pattern/ImplementorA.java @@ -0,0 +1,8 @@ +package bridge.pattern; + +public class ImplementorA implements Implementor{ + + public void operacion() { + System.out.println("Esta es la implementacion A"); + } +} diff --git a/src/bridge/pattern/ImplementorB.java b/src/bridge/pattern/ImplementorB.java new file mode 100644 index 0000000..de2a3a9 --- /dev/null +++ b/src/bridge/pattern/ImplementorB.java @@ -0,0 +1,9 @@ +package bridge.pattern; + +public class ImplementorB implements Implementor{ + + public void operacion() { + System.out.println("Esta es la implementacion B"); + } + +} diff --git a/src/bridge/pattern/RefinedAbstraction.java b/src/bridge/pattern/RefinedAbstraction.java new file mode 100644 index 0000000..4484925 --- /dev/null +++ b/src/bridge/pattern/RefinedAbstraction.java @@ -0,0 +1,14 @@ +package bridge.pattern; + +public class RefinedAbstraction implements Abstraction{ + + private Implementor implementador; + + public RefinedAbstraction(Implementor implementador){ + this.implementador = implementador; + } + public void operacion(){ + implementador.operacion(); + } + +}