name: title class: middle, center background-image: url(images/rawpixel/brooklyn-bridge.jpg) background-size: cover # .whiteinline[.fancy[[TE5] Patrones Estructurales]] ### .whiteinline[· Adapter pattern] .whiteinline[Carlos Granell· Universitat Jaume I] .whiteinline[EI1039 - Diseño de Software · Sep 2023] ??? Brooklyn Bridge, New York City, United States. Original public domain image from Wikimedia Commons. Image credits: [Rawpixel.com](https://www.rawpixel.com/image/3282163) Categoría [Estructurales](https://cgranell.github.io/ei1039/slides/TE1_intro_patrones.html#p10): Analogía es el maridaje culinario cuando juntamos ingrediantes de distintas formas para formar nuevas relacionas, ya sea combinando ingredientes físicalmente (ensalada) o sin combinación (queso y vino) --- class: inverse, center, middle background-image: url(images/DivingDesingPatterns04.png) background-size: contain ??? Image credits: [refactoring.guru](https://refactoring.guru/es/design-patterns/adapter) --- class: inverse, center, middle # Adapter Pattern .large[Propósito] .large[Problema] .large[Solución] .large[Estructura] .large[Aplicabilidad] --- name: purpose class: center, middle # Adapter: Propósito ## objetos con interfaces .heatinline[incompatibles] pasan a ser .coldinline[compatibles] --- name: problem # Adapter: Problema ### Objetos con interfaces incompatibles no pueden comunicarse directamente ### Salida de un sistema/objeto
entrada de otro sistema/objeto --- # Adapter: Problema .large[En tu código, deseas llamar a un servicio web con interfaces incompatibles (*payload* en XML *vs.* JSON)] -- .pull-left[ ```java public class Client { public void doLocalAnalysis(XML data) { } } ``` ] .pull-right[ ```java public class WebService { public int doBetterAnalysis(Json request) { } } ``` ] --- name: solution # Adapter: Problema .large[Aha!, modifico la clase cliente...] .pull-left[ ```java public class Client { public void doLocalAnalysis(XML data) { } * public int doBetterAnalysisWS(XML data) * { * // Conversión de XML a JSON * // Llamada al Web Service * } } ``` ] .pull-right[ ```java public class WebService { public int doBetterAnalysis(Json request) { } } ``` ] ??? Una solución rápida es cambiar la clase cliente para que pueda llamar al servicio web externo directamente --- class: middle # .center[😠] -- ###
[Encapsula lo que varía y sepáralo de lo que no cambia](https://cgranell.github.io/ei1039/slides/TE3_solid.html#principle-encapsulate) ###
[Programa a una interfaz, no a una implementación](https://cgranell.github.io/ei1039/slides/TE3_solid.html#principle-interface) ###
[Clases abiertas a la extensión pero cerradas a la modificación](https://cgranell.github.io/ei1039/slides/TE3_solid.html#ocp) (SOLID) ??? La solución rápida rompe los principios básicos de diseño. --- # Adapter: Solución ### Un _adaptador_ envuelve la interfaz de un objeto (`Service`), de forma que otro objeto (`Client`) pueda utilizarla ### Un _adaptador_ se sitúa entre `Client` y `Service`, los cuales están completamente _desacoplados_ -- > 1. .large[Crea una interfaz que utilizará el cliente `Client`] > 2. .large[Implementa dicha interfaz con una clase `Adapter`] > 3. .large[La clase `Adapter` se comunica con `Service`, siendo transparente para `Client`] --- name: structure # Adapter: Estructura <img src="images/DivingDesingPatterns05.png" width="90%"/> ??? Image credits: [refactoring.guru](https://refactoring.guru/es/design-patterns/adapter) --- #
¿Qué tipo de clase es `Adapter`? .large[
Una clase `Wrapper`] .large[
Una clase `Superclass`] .large[
Una clase `Interface`] .large[
Una clase `Abstract`] ??? 1000: Un *Adapter* encapsula (*wrapper*) la clase adaptada y presenta una nueva interfaz al cliente. No es una interfaz en sí mismo. --- name: aplicability # Adapter: Aplicabilidad .large[
Cuando incorporas clases existentes de terceros (librerías, servicios, etc.), pero cuya interfaz no es compatible con tu código/sistema] .large[
Cuando necesitas transformación de datos, formatos, etc. entre objetos] --- #
Los beneficios del patrón `Adapter` son .large[
Relaciona el cliente a una interfaz, no a una implementación] .large[
La clase existente adaptada no cambia] .large[
Limita la propagación de efectos secundarios ya que no se descompone el cliente] .large[
Implementa el [Principio de Inversión de Dependencia](https://cgranell.github.io/ei1039/slides/TE3_solid.html#dip)] ??? 1111 --- name: summary # Resumen ### El patrón Adapter.... .large[
envuelve la clase adaptada y expone una interfaz al cliente] .large[
cambia indirectamente la interfaz de la clase adaptada a una que el cliente comprende, implementando la nueva interfaz] .large[
traduce indirectamente la solicitud del cliente en una petición que la clase adaptada espera/entiende] .large[
reutiliza una clase adaptada existente que tiene una interfaz incompatible]