Patrón estructural Adapter (Python) - fapaccha/Dise-o-dirigido-por-el-modelo GitHub Wiki
Adapter(Python)
Adapter es un patrón de diseño estructural que permite la colaboración entre objetos con interfaces incompatibles.
Estructura
Esta implementación utiliza el principio de composición de objetos: el adaptador implementa la interfaz de un objeto y envuelve el otro. Puede implementarse en todos los lenguajes de programación populares.
Estructura del patrón de diseño Adapter (el adaptador de objetos) La clase Cliente contiene la lógica de negocio existente del programa.
La Interfaz con el Cliente describe un protocolo que otras clases deben seguir para poder colaborar con el código cliente.
Servicio es alguna clase útil (normalmente de una tercera parte o heredada). El cliente no puede utilizar directamente esta clase porque tiene una interfaz incompatible.
La clase Adaptadora es capaz de trabajar tanto con la clase cliente como con la clase de servicio: implementa la interfaz con el cliente, mientras envuelve el objeto de la clase de servicio. La clase adaptadora recibe llamadas del cliente a través de la interfaz adaptadora y las traduce en llamadas al objeto envuelto de la clase de servicio, pero en un formato que pueda comprender.
El código cliente no se acopla a la clase adaptadora concreta siempre y cuando funcione con la clase adaptadora a través de la interfaz con el cliente. Gracias a esto, puedes introducir nuevos tipos de adaptadores en el programa sin descomponer el código cliente existente. Esto puede resultar útil cuando la interfaz de la clase de servicio se cambia o sustituye, ya que puedes crear una nueva clase adaptadora sin cambiar el código cliente.
Cómo implementarlo
- Asegúrate de que tienes al menos dos clases con interfaces incompatibles:
- Una útil clase servicio que no puedes cambiar (a menudo de un tercero, heredada o con muchas dependencias existentes).
- Una o varias clases cliente que se beneficiarían de contar con una clase de servicio. Declara la interfaz con el cliente y describe el modo en que las clases cliente se comunican con la clase de servicio.
-
Crea la clase adaptadora y haz que siga la interfaz con el cliente. Deja todos los métodos vacíos por ahora.
-
Añade un campo a la clase adaptadora para almacenar una referencia al objeto de servicio. La práctica común es inicializar este campo a través del constructor, pero en ocasiones es adecuado pasarlo al adaptador cuando se invocan sus métodos.
-
Uno por uno, implementa todos los métodos de la interfaz con el cliente en la clase adaptadora. La clase adaptadora deberá delegar la mayor parte del trabajo real al objeto de servicio, gestionando tan solo la interfaz o la conversión de formato de los datos.
-
Las clases cliente deberán utilizar la clase adaptadora a través de la interfaz con el cliente. Esto te permitirá cambiar o extender las clases adaptadoras sin afectar al código cliente.
class Target:
"""
Define la interfaz especifica del dominio utilizada por el cliente
"""
def request(self) -> str:
return "Objetivo: el comportamiento del objetivo predeterminado."
class Adaptee:
"""
El adaptador contiene un comportamiento útil, pero su interfaz es
incompatible con el código de cliente existente. El Adaptador necesita
alguna adaptación antes de que el código del cliente pueda usarlo.
"""
def specific_request(self) -> str:
return ".eetpada esalc al ed laicepse otneimatropmoc"
class Adapter(Target, Adaptee):
"""
El adaptador hace que la interfaz del Adaptee sea compatible con la
interfaz del objetivo mediante herencia múltiple.
"""
def request(self) -> str:
return f"Adapter: (Trduccion) {self.specific_request()[::-1]}"
def client_code(target: "Target") -> None:
"""
El código de cliente admite todas las clases que siguen la interfaz de destino.
"""
print(target.request(), end="")
if __name__ == "__main__":
print("Cliente: puedo trabajar bien con los objetos de destino:")
target = Target()
client_code(target)
print("\n")
adaptee = Adaptee()
print("Cliente: la clase Adaptee tiene una interfaz extraña. "
"No se entiende:")
print(f"Adaptee: {adaptee.specific_request()}", end="\n\n")
print("Cliente: Pero puedo trabajar con él a través del Adaptador:")
adapter = Adapter()
client_code(adapter)