mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-15 18:59:10 +00:00
dc7495e8bd
* Typo corrections * bridge pattern translated to spanish * builder pattern translated to spanish * context-object pattern translated to spanish * converter pattern translated to spanish * dependency injection pattern translated to spanish * factory pattern translated to spanish * factory-kit pattern translated to spanish * factory-method pattern translated to spanish * monostate pattern translated to spanish * multiton pattern translated to spanish * object mother pattern translated to spanish * object pool pattern translated to spanish * property pattern translated to spanish * prototype pattern translated to spanish * registry pattern translated to spanish * step builder pattern translated to spanish * value object pattern translated to spanish * typo corrections and resources urls refactor * grammar corrections * Add image to each pattern --------- Co-authored-by: luismateoh <luismateohm@gmail.com> Co-authored-by: luis.hincapie <luis.hincapie@blankfactor.com>
223 lines
6.1 KiB
Markdown
223 lines
6.1 KiB
Markdown
---
|
|
title: Bridge
|
|
category: Structural
|
|
language: es
|
|
tag:
|
|
- Gang of Four
|
|
---
|
|
|
|
## También conocido como
|
|
|
|
Handle/Body
|
|
|
|
## Intención
|
|
|
|
Desacoplar una abstracción de su implementación para que ambas puedan variar de forma independiente.
|
|
|
|
## Explicación
|
|
|
|
Real-world example
|
|
|
|
> Imagina que tienes un arma con diferentes encantamientos, y se supone que debes permitir la mezcla de diferentes armas
|
|
> con diferentes encantamientos. ¿Qué harías? ¿Crearías múltiples copias de cada una de las armas para cada uno de los
|
|
> encantamientos o simplemente crearías un encantamiento separado y lo establecerías para el arma según sea necesario?
|
|
> El
|
|
> patrón Bridge te permite hacer lo segundo.
|
|
|
|
En palabras sencillas
|
|
|
|
> El patrón Bridge se trata de preferir la composición sobre la herencia. Los detalles de implementación se empujan de
|
|
> una jerarquía a otro objeto con una jerarquía separada.
|
|
|
|
Wikipedia dice
|
|
|
|
> El patrón bridge es un patrón de diseño utilizado en ingeniería de software que tiene como objetivo "desacoplar una
|
|
> abstracción de su implementación para que las dos puedan variar independientemente"
|
|
|
|
**Ejemplo programático**
|
|
|
|
Transladando nuestro ejemplo de arma de arriba. Aquí tenemos la interfaz arma `Weapon`:
|
|
|
|
```java
|
|
public interface Weapon {
|
|
void wield();
|
|
void swing();
|
|
void unwield();
|
|
Enchantment getEnchantment();
|
|
}
|
|
|
|
public class Sword implements Weapon {
|
|
|
|
private final Enchantment enchantment;
|
|
|
|
public Sword(Enchantment enchantment) {
|
|
this.enchantment = enchantment;
|
|
}
|
|
|
|
@Override
|
|
public void wield() {
|
|
LOGGER.info("The sword is wielded.");
|
|
enchantment.onActivate();
|
|
}
|
|
|
|
@Override
|
|
public void swing() {
|
|
LOGGER.info("The sword is swinged.");
|
|
enchantment.apply();
|
|
}
|
|
|
|
@Override
|
|
public void unwield() {
|
|
LOGGER.info("The sword is unwielded.");
|
|
enchantment.onDeactivate();
|
|
}
|
|
|
|
@Override
|
|
public Enchantment getEnchantment() {
|
|
return enchantment;
|
|
}
|
|
}
|
|
|
|
public class Hammer implements Weapon {
|
|
|
|
private final Enchantment enchantment;
|
|
|
|
public Hammer(Enchantment enchantment) {
|
|
this.enchantment = enchantment;
|
|
}
|
|
|
|
@Override
|
|
public void wield() {
|
|
LOGGER.info("The hammer is wielded.");
|
|
enchantment.onActivate();
|
|
}
|
|
|
|
@Override
|
|
public void swing() {
|
|
LOGGER.info("The hammer is swinged.");
|
|
enchantment.apply();
|
|
}
|
|
|
|
@Override
|
|
public void unwield() {
|
|
LOGGER.info("The hammer is unwielded.");
|
|
enchantment.onDeactivate();
|
|
}
|
|
|
|
@Override
|
|
public Enchantment getEnchantment() {
|
|
return enchantment;
|
|
}
|
|
}
|
|
```
|
|
|
|
Aquí está la interfaz de encantamientos `Enchantment` separada:
|
|
|
|
```java
|
|
public interface Enchantment {
|
|
void onActivate();
|
|
void apply();
|
|
void onDeactivate();
|
|
}
|
|
|
|
public class FlyingEnchantment implements Enchantment {
|
|
|
|
@Override
|
|
public void onActivate() {
|
|
LOGGER.info("The item begins to glow faintly.");
|
|
}
|
|
|
|
@Override
|
|
public void apply() {
|
|
LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand.");
|
|
}
|
|
|
|
@Override
|
|
public void onDeactivate() {
|
|
LOGGER.info("The item's glow fades.");
|
|
}
|
|
}
|
|
|
|
public class SoulEatingEnchantment implements Enchantment {
|
|
|
|
@Override
|
|
public void onActivate() {
|
|
LOGGER.info("The item spreads bloodlust.");
|
|
}
|
|
|
|
@Override
|
|
public void apply() {
|
|
LOGGER.info("The item eats the soul of enemies.");
|
|
}
|
|
|
|
@Override
|
|
public void onDeactivate() {
|
|
LOGGER.info("Bloodlust slowly disappears.");
|
|
}
|
|
}
|
|
```
|
|
|
|
Aquí están ambas interfaces en acción:
|
|
|
|
```java
|
|
LOGGER.info("The knight receives an enchanted sword.");
|
|
var enchantedSword = new Sword(new SoulEatingEnchantment());
|
|
enchantedSword.wield();
|
|
enchantedSword.swing();
|
|
enchantedSword.unwield();
|
|
|
|
LOGGER.info("The valkyrie receives an enchanted hammer.");
|
|
var hammer = new Hammer(new FlyingEnchantment());
|
|
hammer.wield();
|
|
hammer.swing();
|
|
hammer.unwield();
|
|
```
|
|
|
|
Aquí está la salida en consola.
|
|
|
|
```
|
|
The knight receives an enchanted sword.
|
|
The sword is wielded.
|
|
The item spreads bloodlust.
|
|
The sword is swung.
|
|
The item eats the soul of enemies.
|
|
The sword is unwielded.
|
|
Bloodlust slowly disappears.
|
|
The valkyrie receives an enchanted hammer.
|
|
The hammer is wielded.
|
|
The item begins to glow faintly.
|
|
The hammer is swung.
|
|
The item flies and strikes the enemies finally returning to owner's hand.
|
|
The hammer is unwielded.
|
|
The item's glow fades.
|
|
```
|
|
|
|
## Diagrama de Clases
|
|
|
|

|
|
|
|
## Aplicabilidad
|
|
|
|
Usa el patrón Bridge cuando
|
|
|
|
* Quieres evitar una vinculación permanente entre una abstracción y su implementación. Este podría ser el caso, por
|
|
ejemplo, cuando la implementación debe ser seleccionada o cambiada en tiempo de ejecución.
|
|
* Tanto las abstracciones como sus implementaciones deberían ser extensibles mediante la herencia. En este caso, el
|
|
patrón Bridge te permite combinar las diferentes abstracciones e implementaciones y extenderlas de forma
|
|
independiente.
|
|
* Los cambios en la implementación de una abstracción no deberían tener impacto en los clientes; es decir, su código no
|
|
debería tener que ser recompilado.
|
|
* Tienes una proliferación de clases. Tal jerarquía de clases indica la necesidad de dividir un objeto en dos partes.
|
|
Rumbaugh usa el término "generalizaciones anidadas" para referirse a tales jerarquías de clases.
|
|
* Quieres compartir una implementación entre varios objetos (quizás usando conteo de referencias), y este hecho debería
|
|
ser ocultado al cliente. Un ejemplo simple es la clase String de Coplien, en la que varios objetos pueden compartir la
|
|
misma representación de cadena.
|
|
|
|
## Tutoriales
|
|
|
|
* [Bridge Pattern Tutorial](https://www.journaldev.com/1491/bridge-design-pattern-java)
|
|
|
|
## Créditos
|
|
|
|
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
|
|
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) |