hogar - Seguridad
Patrón de diseño del adaptador. Patrón de diseño de adaptador en PHP

Última actualización: 31/10/2015

El patrón Adaptador está diseñado para convertir la interfaz de una clase en la interfaz de otra. Gracias a la implementación de este patrón, podemos usar clases con interfaces incompatibles juntas.

¿Cuándo debería utilizar el adaptador?

    Cuando necesita utilizar una clase existente, pero su interfaz no satisface sus necesidades

    Cuando necesita utilizar una clase existente junto con otras clases cuyas interfaces son incompatibles

La definición formal de un patrón en UML es la siguiente:

La descripción formal de un adaptador de objetos en C# tiene este aspecto:

Cliente de clase ( Solicitud public void (objetivo objetivo) ( target.Request(); ) ) // clase a la que se debe adaptar otra clase class Target ( Solicitud public virtual void () () ) // Clase de adaptador Adaptador: Destino ( Adaptee privado adaptee = nuevo Adaptee(); anulación pública void Request() ( adaptee.SpecificRequest(); ) ) // Clase adaptable clase Adaptee ( public void SpecificRequest() () )

Participantes

    Destino: representa objetos que son utilizados por el cliente.

    Cliente: utiliza objetos Target para implementar sus tareas

    Adaptee: Representa la clase adaptable que nos gustaría que el cliente use en lugar de los objetos Target.

    Adaptador: el adaptador real, que le permite trabajar con objetos Adaptee como con objetos Target.

Es decir, el cliente no sabe nada sobre Adaptee, solo conoce y utiliza los objetos Target. Y gracias al adaptador, podemos usar objetos Adaptee como Target en el cliente.

Ahora veamos un ejemplo real. Digamos que tenemos un viajero que viaja en coche. Pero en algún momento tiene que moverse por las arenas del desierto, donde no puede conducir un coche. Pero puede usar un camello para moverse. Sin embargo, la clase viajero no permite la clase camello, por lo que necesitamos utilizar un adaptador:

Programa de clase ( static void Main(string args) ( // viajero Conductor conductor = nuevo Conductor(); // coche Auto auto = nuevo Auto(); // vamos de viaje conductor.Travel(auto); // arenas Para cumplir, necesitamos usar un camello Camel camel = new Camel(); // usar el adaptador ITransport camelTransport = new CamelToTransportAdapter(camel); // continuar el camino a través de las arenas del desierto driver.Travel(camelTransport); Console.Read( ); ) ) interfaz ITransport ( void Drive(); ) // clase de coche class Auto: ITransport ( public void Drive() ( Console.WriteLine("El coche circula por la carretera"); ) ) class Driver ( public void Travel(ITransport transporte) ( transport.Drive() ; ) ) // interfaz animal interfaz IAnimal ( void Move(); ) // clase de camello class Camel: IAnimal ( public void Move() ( Console.WriteLine("El camello camina a lo largo de las arenas del desierto"); ) ) // Adaptador de Camel a ITransport clase CamelToTransportAdapter: ITransport ( Camel camel; public CamelToTransportAdapter(Camel c) ( camel = c; ) unidad pública vacía() ( camello.Move(); ) )

Y la consola generará:

Un coche circula por la carretera, un camello camina por las arenas del desierto.

En este caso, se utiliza la clase Driver como cliente, que utiliza el objeto ITransport. El adaptable es la clase Camel Camel, que debe usarse como un objeto ITransport. Y el adaptador es la clase CamelToTransportAdapter.

Algunos pueden encontrar que el problema de usar adaptadores es inverosímil, especialmente en este caso, ya que podríamos aplicar la interfaz ITransport a la clase Camel e implementar su método Drive(). Sin embargo, en este caso, puede haber duplicación de funcionalidad: la interfaz IAnimal tiene un método Move(), cuya implementación en la clase camel podría ser similar a la implementación del método Drive() de la interfaz ITransport. Además, a menudo sucede que las clases las diseña otra persona y no tenemos ninguna influencia sobre ellas. Simplemente los usamos. Como resultado, los adaptadores son bastante comunes en .NET. En particular, numerosas clases integradas que se utilizan para conectarse a varios sistemas de bases de datos implementan el patrón del adaptador (por ejemplo, la clase System.Data.SqlClient.SqlDataAdapter).

Antes de leer, revise las siguientes convenciones y conceptos. Este artículo se actualiza con cierta frecuencia, por lo que si lo has leído antes no es un hecho que los datos no hayan cambiado.

Adaptador pertenecer a la clase estructural patrones. Se utiliza para convertir una interfaz a otra requerida por el cliente. El adaptador garantiza la compatibilidad de interfaces incompatibles mediante la implementación de una capa.

Principio de funcionamiento

El adaptador hereda la interfaz de destino de forma abierta (llamémosla Objetivo), y una interfaz adaptable de forma cerrada ( Adaptado). En la implementación de los métodos de la interfaz de destino, las solicitudes se redirigen (delegan) a una clase con una interfaz adaptable.

Ejemplo

// Interfaz de destino, el cliente solo puede trabajar con ella interfaz iTarget ( public function query(); ) // Interfaz adaptable. El cliente no sabe cómo trabajar con él, pero realmente quiere la interfaz iAdaptee ( public function request(); ) // Una clase que implementa una interfaz adaptable clase Adaptee implementa iAdaptee ( public function request() ( return __CLASS__ . ":: " . __METHOD__; ) ) clase Adaptador implementa iTarget ( protegido $adaptee = null; función pública __construct() ($this -> adaptee = new Adaptee(); ) función pública query() ( return $this -> adaptee -> solicitud (); ) ) $ Destino = nuevo Adaptador(); imprimir $Objetivo -> consulta(); // "Adaptado::solicitud"

Conclusión

Un adaptador puede adaptar varias interfaces en una sola a la vez; este patrón se llama adaptador de objetos El uso de este patrón está justificado en varios casos. Si desea utilizar una clase existente con una interfaz diferente. Si va a utilizar la interfaz adaptable en varios lugares y no tiene la oportunidad de hacer que se vea igual en todas partes, entonces puede ser una buena idea utilizar adaptadores reemplazables.

En la última lección, analizamos la posibilidad del patrón de diseño Fachada, con el que puedes reconstruir el código de un proyecto grande.

En este artículo, nos centraremos en un patrón de diseño llamado Adaptador. Su uso es recomendable si su proyecto interactúa con API de terceros u otra clase que esté sujeta a cambios frecuentes. Esta plantilla pertenece al tipo “estructural” porque Con su ayuda podemos organizar la estructura de clases de acuerdo con un patrón determinado.

Una vez más me gustaría recordarles que los patrones de diseño no se diferencian de las clases normales. Con su ayuda podremos estructurar mejor nuestras clases y controlar su comportamiento.

Tarea

En el ejemplo anterior, utilizamos la clase Twitter para simplificar el procedimiento de publicación de un mensaje. A continuación, creamos un objeto para llamar a la API de Twitter y publicar un mensaje. Imagine que este código se utiliza en varios lugares. Tenga en cuenta que para publicar un mensaje utilizamos el método $twitter->send("Publicar en Twitter");

Hace algún tiempo, Twitter cambió el nombre del método API para publicar un mensaje. Quienes utilizaron la versión anterior verán claramente el problema. Necesitamos cambiar todos los nombres de los métodos para enviar un tweet. Imagínese cuánto código necesitamos cambiar y cuánto tiempo llevará. ¿Qué pasa si el cambio de nombre se repite?

Solución

Como solución, podemos utilizar el patrón de diseño Adaptador.

Un adaptador es un patrón de diseño estructural diseñado para organizar el uso de las funciones de un objeto que no está disponible para modificación a través de una interfaz creada especialmente.

Entonces, antes que nada, necesitamos crear una interfaz. Cambiar el código de una biblioteca de terceros no tiene ningún sentido, porque... su contenido puede cambiar en cualquier momento.

Veamos algo de código escrito usando el patrón de diseño del Adaptador:

// Implementación de la clase Twitter class Twitter ( public function __construct() ( // Tu código aquí // ) public function send($msg) ( // Publicar en Twitter // echo $msg; ) ) // Interfaz simple para cada adaptador, que se creará interfaz socialAdapter (función pública enviar ($msg);) clase twitterAdapter implementa socialAdapter (privado $twitter; función pública __construct(Twitter $twitter) ($this->twitter = $twitter;) función pública enviar ($msg) ( $this->twitter->enviar($msg); ) )

Después de examinar el código, se dará cuenta de que no hemos tocado la clase original de Twitter. En lugar de eso, creamos nuestra interfaz de adaptador social para la clase de Twitter.

A continuación, en lugar de crear un objeto de tipo Twitter, creamos un objeto de su adaptador. Pasamos un objeto de la clase principal de Twitter como parámetro para que nuestro adaptador tenga acceso al objeto de la clase principal.

Ahora definamos cómo usar los métodos de la clase original:

// código de cliente $twitter = nuevo twitterAdapter(nuevo Twitter()); $twitter->send("Publicar en Twitter");

Ahora imagina que Twitter cambió el nombre del método de enviar a enviarTweet. En este caso, sólo necesitamos cambiar twitterAdapter. Eche un vistazo al código del adaptador modificado.

La clase twitterAdapter implementa socialAdapter (privado $twitter; función pública __construct(Twitter $twitter) ( $this->twitter = $twitter; ) función pública enviar($msg) ( $this->twitter->sendTweet($msg); ) )

Sólo un cambio y volvemos a la normalidad.

Agregar un nuevo adaptador

Veamos cómo se puede utilizar el patrón de diseño del Adaptador en otros casos. Ahora es muy fácil agregar una nueva clase basada en un adaptador existente. Digamos que la API de Facebook te permite actualizar tu estado.

En lugar de usar la clase de Facebook directamente, creemos un nuevo adaptador.

Clase Facebook ( public function __construct() ( // Su código // ) public function updateStatus($msg) ( // Publicar en Facebook // echo $msg; ) ) // La clase de adaptador de Facebook facebookAdapter implementa socialAdapter ( private $facebook; función pública __construct(Facebook $facebook) ( $this->facebook = $facebook; ) función pública enviar($msg) ( $this->facebook->updateStatus($msg); ) ) // código de cliente $facebook = nuevo facebookAdapter(nuevo Facebook()); $facebook->send("Publicar en Facebook");

Como puede ver, el principio es el mismo. Usted define una clase contenedora a la que pasa el objeto de clase original. Al cambiar la API, solo necesita cambiar el código en un lugar.

Conclusión

Sin duda, las aplicaciones grandes implicarán trabajar con API de terceros, por lo que usar el patrón de diseño del Adaptador tiene sentido si desea evitar el problema que analizamos.

He hecho todo lo posible para demostrar un ejemplo básico pero útil del uso del patrón de diseño del Adaptador.

    Adaptador (patrón de diseño)/ejemplos de código- Artículo principal: Adaptador (patrón de diseño) Un ejemplo de implementación de un patrón en C# usando System; Adaptador de espacio de nombres ( clase MainApp ( static void Main() ( ... Wikipedia

    Patrón proxy (patrón de diseño)

    Patrón de diseño- Este término tiene otros significados, consulte Patrón. En el desarrollo de software, un patrón de diseño es un diseño arquitectónico repetible que representa una solución a un problema... ... Wikipedia

    Interfaz (patrón de diseño)- Interfaz de patrón de diseño descrita en Patrones de diseño No En informática, el patrón de interfaz no es un patrón especial entre los patrones de diseño. Es un método general para estructurar programas informáticos con el fin de... Wikipedia

    Adjunto (patrón de diseño)- Patrón de diseño Proxy Pattern (Suplente). Proporciona un objeto de control de acceso, interceptando todas las llamadas al mismo. Contenido 1 Objetivo 1.1 Problema 1.2 Solución 2 Ventajas 3 ... Wikipedia

    Guardián (patrón de diseño)- Patrón de diseño Guardian Memento Tipo: Comportamiento Descrito en Patrones de diseño Sí Guardian (también conocido como Memento, Token, Token) es un patrón de diseño de comportamiento. Le permite arreglar sin romper la encapsulación... Wikipedia

    Iterador (patrón de diseño)- Iterador de patrón de diseño Tipo de iterador: conductual Descrito en Patrones de diseño Sí Patrón de iterador (también conocido como cursor) Un patrón de diseño que hace referencia a patrones de comportamiento. Es un objeto que permite conseguir… Wikipedia

    Intérprete (patrón de diseño)- Patrón de diseño Tipo de intérprete: conductual Propósito: resuelve un problema que ocurre con frecuencia y propenso a cambios Descrito en Patrones de diseño Sí Patrón de intérprete (inglés ... Wikipedia

    Vinculador (patrón de diseño)- Patrón de diseño Tipo compuesto: estructural Descrito en Patrones de diseño Sí El patrón compuesto es un patrón de diseño, se refiere a patrones estructurales, combina un objeto... Wikipedia

    Estado (patrón de diseño)- Patrón de diseño de estado Tipo: conductual Descrito en Patrones de diseño Sí El estado es un patrón de diseño. Se utiliza en los casos en que, durante la ejecución del programa, un objeto ... Wikipedia

Volvamos a la consideración de los patrones de diseño estructural. Esta vez veremos un patrón de diseño llamado Adaptador(también se le llama Wrapper junto con el patrón Fachada).

En este artículo hablaremos de lo siguiente:

Entonces, el patrón Adaptador se usa para que los objetos con una interfaz (contrato) puedan funcionar donde se necesita un objeto con una interfaz completamente diferente. Hay dos tipos de adaptadores: adaptador de clase y adaptador de objeto.

Primero, veremos cada uno de estos tipos y luego explicaré la diferencia entre los dos envoltorios: adaptador y fachada.

Adaptador de objetos

Object Adapter logra su objetivo a través de la composición. En el siguiente diagrama, el cliente debe utilizar la interfaz TargetInterface. Para hacer esto, se crea una clase ObjectAdapter que implementa la interfaz TargetInterface y también almacena un objeto de clase Adaptee. Al llamar al método targetMethod en el Adaptador, se llama al método correspondiente en la interfaz que se está adaptando.

En el caso más sencillo, la implementación de ObjectAdapter sería así:

La clase pública ObjectAdapter implementa TargetInterface (adaptee privado adaptado; targetMethod público vacío() (adaptee.method()))

La ventaja de este enfoque es que separamos completamente la interfaz del cliente de la interfaz adaptable.

Adaptador de clase

En el caso de Class Adapter, se utiliza herencia múltiple para lograr nuestro objetivo. Nuestro ClassAdapter hereda de la interfaz del cliente y de la interfaz Adaptable. Dado que no existe herencia múltiple en Java, solo uno de los ancestros puede ser una clase abstracta/concreta. El segundo ancestro será la interfaz, lo cual no siempre es conveniente.

Diagrama de clase:

Y aquí hay una implementación trivial de la clase ClassAdapter:

La clase pública ClassAdapter extiende los implementos Adaptee TargetInterface (public void targetMethod() (método();))

Me gustaría llamar su atención sobre el hecho de que con tal implementación del adaptador puede surgir un conflicto en las firmas de los métodos. El Adaptador de objetos no tiene este problema.

Class Adapter se considera una solución más sencilla cuando no se requiere una separación estricta entre el cliente y las interfaces adaptables.

Diferencia entre Adaptador y Fachada

Ahora quiero decir unas palabras sobre el patrón Facade, que, al igual que el Adaptador, es un Wrapper. nuevo interfaz mientras el adaptador está utilizando existente interfaces.

No deberías comparar Facade y Adapter de esta manera: dicen que Facade puede incluir varias clases, pero Adapter adapta solo una. Es muy posible que el Adaptador sea necesario para adaptar varias clases y, viceversa, que la Fachada deba usarse para simplificar solo una clase compleja. Entonces, la diferencia entre estos dos patrones no está en la cantidad de entidades que se envuelven, sino en por qué lo hacen.

Ejemplo de uso del Adaptador en JDK

También puede encontrar ejemplos del uso del Adaptador en la biblioteca estándar. Probablemente el caso de uso más popular sea java.io.InputStreamReader y OutputStreamWriter.

El constructor InputStreamReader toma un InputStream como entrada y, como resultado, adapta la secuencia al Reader.

Más adelante publicaré código para usar Adaptadores de proyectos reales en los que participé, pero por ahora estoy esperando sus preguntas y comentarios. Buena suerte.



 


Leer:



Mini prueba de pensamiento técnico.

Mini prueba de pensamiento técnico.

Diagnóstico integral de las capacidades generales de los adolescentes en el contexto de la educación especializada PARTE III 3. Diagnóstico de la esfera cognitiva 3.3. Prueba...

Envíe un anuncio para la venta de un apartamento, casa y otros bienes inmuebles de forma gratuita Envíe un anuncio para la venta rápida de una casa

Envíe un anuncio para la venta de un apartamento, casa y otros bienes inmuebles de forma gratuita Envíe un anuncio para la venta rápida de una casa

Vender una vivienda es un proceso complejo que requiere tener en cuenta una serie de matices. Para acelerar el proceso, los expertos aconsejan recurrir a profesionales. Sin embargo...

Ganar dinero leyendo cartas Leer cartas pero recompensas por

Ganar dinero leyendo cartas Leer cartas pero recompensas por

La forma más sencilla de ganar dinero en Internet, donde puedes empezar a trabajar, es ganar dinero leyendo las cartas publicitarias que te envían los anunciantes...

Material sobre el tema: Programa de conciertos “Con todo mi corazón” Programa de televisión Con todo mi corazón todos los episodios

Material sobre el tema: Programa de conciertos.

En general, el programa hablaba de los destinos complejos e impredecibles del pueblo soviético. La mayoría de los espectadores no pudieron contener las lágrimas cuando...

imagen-feed RSS