|
| 1 | +--- |
| 2 | +title: Adapter |
| 3 | +category: Structural |
| 4 | +language: es |
| 5 | +tags: |
| 6 | + - Gang of Four |
| 7 | +--- |
| 8 | + |
| 9 | +## También conocido como |
| 10 | +Wrapper |
| 11 | + |
| 12 | +## Propósito |
| 13 | +Convertir la interfaz de una clase en otra que espera el cliente. El patrón Adapter permite a clases funcionar en conjunto con otras clases con las que no podrían de otra forma por problemas de compatibilidad. |
| 14 | + |
| 15 | +## Explicación |
| 16 | + |
| 17 | +Ejemplo del mundo real |
| 18 | + |
| 19 | +> Imagina que tienes unas imágenes en una tarjeta de memoria y quieres transferirlas a tu ordenador. Para transferirlas necesitas algún tipo de adaptador compatible con los puertos de tu ordenador que te permita introducir tu tarjeta. En este caso el lector de tarjetas es un adaptador (adapter). |
| 20 | +> Otro ejemplo podría ser el famoso adaptador de corriente; un enchufe con tres patas no se puede conectar a una toma de corriente con dos agujeros, necesita un adaptador para hacerlo compatible con la toma de corriente. |
| 21 | +> Otro ejemplo mas seria un traductor traduciendo palabras de una persona para otra. |
| 22 | +
|
| 23 | +En otras palabras |
| 24 | + |
| 25 | +> El patrón Adapter permite envolver un objeto en un adaptador para hacerlo compatible con una clase con la que seria incompatible de otra manera. |
| 26 | +
|
| 27 | +Según Wikipedia |
| 28 | + |
| 29 | +> En ingeniería de software el patrón Adapter es un patrón de diseño de software que permite usar la interfaz de una clase existente como otra interfaz diferente. A menudo es utilizado para hacer que clases existentes trabajen con otras clases sin necesidad de modificar su código fuente. |
| 30 | +
|
| 31 | +**Ejemplo Programático** |
| 32 | + |
| 33 | +Toma como ejemplo un capitán que solo puede usar botes de remo y no puede navegar en absoluto. |
| 34 | + |
| 35 | +Primero tenemos las interfaces `RowingBoat` (bote de remo) y `FishingBoat` (bote de pesca). |
| 36 | + |
| 37 | +```java |
| 38 | +public interface RowingBoat { |
| 39 | + void row(); |
| 40 | +} |
| 41 | + |
| 42 | +@Slf4j |
| 43 | +public class FishingBoat { |
| 44 | + public void sail() { |
| 45 | + LOGGER.info("The fishing boat is sailing"); |
| 46 | + } |
| 47 | +} |
| 48 | +``` |
| 49 | + |
| 50 | +Y el capitán espera una implementación de la interfaz `RowingBoat` (bote de remo) para poder moverse. |
| 51 | + |
| 52 | +```java |
| 53 | +public class Captain { |
| 54 | + |
| 55 | + private final RowingBoat rowingBoat; |
| 56 | + // default constructor and setter for rowingBoat |
| 57 | + public Captain(RowingBoat rowingBoat) { |
| 58 | + this.rowingBoat = rowingBoat; |
| 59 | + } |
| 60 | + |
| 61 | + public void row() { |
| 62 | + rowingBoat.row(); |
| 63 | + } |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +Ahora supongamos que viene un grupo de piratas y nuestro capitán tiene que escapar pero solo hay un bote de pesca. Necesitamos crear un adaptador que permita al capitán usar el bote de pesca con sus habilidades para usar botes de remo. |
| 68 | + |
| 69 | +```java |
| 70 | +@Slf4j |
| 71 | +public class FishingBoatAdapter implements RowingBoat { |
| 72 | + |
| 73 | + private final FishingBoat boat; |
| 74 | + |
| 75 | + public FishingBoatAdapter() { |
| 76 | + boat = new FishingBoat(); |
| 77 | + } |
| 78 | + |
| 79 | + @Override |
| 80 | + public void row() { |
| 81 | + boat.sail(); |
| 82 | + } |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +Y ahora el `Captain` (capitán) puede usar el `FishingBoat` (bote de pesca) para escapar de los piratas. |
| 87 | + |
| 88 | +```java |
| 89 | +var captain = new Captain(new FishingBoatAdapter()); |
| 90 | +captain.row(); |
| 91 | +``` |
| 92 | + |
| 93 | +## Diagrama de clases |
| 94 | + |
| 95 | + |
| 96 | +## Aplicación |
| 97 | +Usa el patrón Adapter cuando |
| 98 | + |
| 99 | +* Quieres usar una clase existente y su interfaz no coincide con la que necesitas. |
| 100 | +* Quieres crear una clase reutilizable que coopere con clases que no están relacionadas o con las que su cooperación no estaba planeada, esto es, clases que no necesariamente tienen interfaces compatibles. |
| 101 | +* Necesitas usar varias subclases existentes pero es impráctico adaptar su interfaz creando subclases para todas. Un adaptador puede adaptar la interfaz de la clase padre. |
| 102 | +* Muchas aplicaciones que usan librerías de terceros usan adaptadores como capas intermedias entre la aplicación y la librería para desacoplar la aplicación de la librería. Si es necesario usar otra librería solo hace falta crear un adaptador para la nueva librería sin necesidad de modificar el código de la aplicación. |
| 103 | + |
| 104 | +## Tutoriales |
| 105 | + |
| 106 | +* [Dzone](https://dzone.com/articles/adapter-design-pattern-in-java) |
| 107 | +* [Refactoring Guru](https://refactoring.guru/design-patterns/adapter/java/example) |
| 108 | +* [Baeldung](https://www.baeldung.com/java-adapter-pattern) |
| 109 | + |
| 110 | +## Consecuencias |
| 111 | +Los adaptadores de clases y objetos tienen distintas cualidades. Un adaptador de clases |
| 112 | + |
| 113 | +* Hace la adaptación quedando enlazado a una clase adaptada concreta. Como consecuencia un adaptador de clases no funcionará cuando queramos adaptar una clase y sus subclases. |
| 114 | +* Permite al adaptador modificar el comportamiento de la clase adaptada porque el adaptador es una subclase de la clase adaptada. |
| 115 | +* Usa un solo objeto y no es necesario usar punteros adicionales para referenciar la clase adaptada. |
| 116 | + |
| 117 | +Un adaptador de objetos |
| 118 | + |
| 119 | +* Permite a un solo adaptador trabajar con varias clases, esto es, con la clase adaptada y todas sus subclases (si tiene alguna). El adaptador también puede añadir funcionalidad a todas las clases adaptadas a la vez. |
| 120 | +* Hace mas complicado modificar el comportamiento de la clase adaptada. Sería necesario hacer una subclase de la clase a adaptar y hacer que el adaptador referencie la subclase en lugar de la clase a adaptar. |
| 121 | + |
| 122 | + |
| 123 | +## Ejemplos del mundo real |
| 124 | + |
| 125 | +* [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29) |
| 126 | +* [java.util.Collections#list()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#list-java.util.Enumeration-) |
| 127 | +* [java.util.Collections#enumeration()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#enumeration-java.util.Collection-) |
| 128 | +* [javax.xml.bind.annotation.adapters.XMLAdapter](http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html#marshal-BoundType-) |
| 129 | + |
| 130 | + |
| 131 | +## Créditos |
| 132 | + |
| 133 | +* [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) |
| 134 | +* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) |
| 135 | +* [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) |
| 136 | +* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) |
0 commit comments