miércoles, 29 de abril de 2015

Adapter

Adapter


Propósito: 

Sirve como intermediario entre dos clases, convirtiendo las interfaces de una clase que pueda ser utilizada por otra. 

También conocido como: wrapper (Envoltorio)

Motivación:  
  • Ej: Editor de elementos gráficos (líneas, texto, etc...)
  • Clase abstracta Shape con interfaz de los objetos gráficos, y una subclase por cada tipo de objeto gráfico (LineShape, TextShape, ...).
  • Existe clase externa TextView no intercambiable con TextShape.
  • Soluciones:


          Hacer TextView conforme a Shape
                 No es posible sin el código fuente
                 No es adecuado modificar TextView para cada aplicación concreta.
          Hacer que TextShape adapte la interfaz de TextView a la de Shape.
                 Delegación (object adapter)


                 Herencia múltiple (class adapter)



Aplicabilidad:

El patrón adapter debe ser utilizado cuando:
  • Desee utilizar un objeto en un entorno que espera una interfaz distinta de la ofrecida por el objeto.
  • Deba realizar una traducción entre las interfaces de varios objetos.
  • Un objeto deba actuar como intermediario para un grupo de clases, y solo es posible saber en tiempo de ejecución que clase sera utilizada.

    Estructura:

    Object Adapter


    Class Adapter


    Participantes:

    • Target (Shape): define la interfaz específica de dominio que el cliente usa. 
    • Client (DrawingEditor): colabora con los objetos que implementan la interfaz definida por el target. 
    • Adaptee (TextView): define una interfaz existente que necesita adaptarse. 
    • Adapter (TextShape): adapta la interfaz del objeto adaptado a la definida por el target.
    Colaboraciones:

    El cliente llama a las operaciones en la instancia del Adapter. Luego, el Adapter llama al Adaptee (el adaptado) y lleva a cabo las operaciones pedidas.

    Consecuencias:
    • Object adapter
              Un adapter funciona con varios adaptees (el mismo adaptee y todas sus subclases).
              Dificulta sobrescribir el comportamiento del adaptee.
    • Class adapter
              El adapter hereda el comportamiento del adaptee, y puede sobrescribirlo.
              No sirve para adaptar una clase y todas sus subclases.
              Introduce un único objeto, no hace falta un nivel de indirección para obtener el adaptee.
    • ¿Cuánto adapta un adapter? 
               Depende de la similitud entre las interfaces de adaptee y target
    • Adaptadores bidireccionales
               Dos clientes necesitan ver un objeto de distinta forma

    Implementación:

    • Adaptador “conectable”
             Maximiza la reutilización de las clases
             Se adapta dinámicamente a una de varias clases
             Ejemplo: construir un componente TreeDisplay que muestre gráficamente estructuras                                      jerárquicas
             Debe ser reutilizable, esto es, debe poder mostrar estructuras jerárquicas de distinto tipo, como                       por ejemplo:
                                 jerarquía de directorios (interfaz getSubdirectories)
                                 jerarquía de clases (interfaz getSubclasses)
                                 etc...
    • Adaptador “conectable”


    Código de ejemplo:
    using System;

    class MainApp
    {
      static void Main()
      {
        // Create adapter and place a request
        Target target = new Adapter();
        target.Request();

        // Wait for user
        Console.Read();
      }
    }

    // "Target"
    class Target
    {
      public virtual void Request()
      {
        Console.WriteLine("Called Target Request()");
      }
    }

    // "Adapter"
    class Adapter : Target
    {
      private Adaptee adaptee = new Adaptee();

      public override void Request()
      {
        // Possibly do some other work
        // and then call SpecificRequest
        adaptee.SpecificRequest();
      }
    }

    // "Adaptee"
    class Adaptee
    {
      public void SpecificRequest()
      {
        Console.WriteLine("Called SpecificRequest()");
      }
    }

    Patrones relacionados:

    Bridge: Tiene una estructura similar al Adapter, pero un intento diferente: Su propósito es separar la interface de su implementación así esta puede variar fácilmente y de forma independiente. El propósito del Adapter es el cambio de interface de un objeto existente.
    Decorator: Agrega responsabilidades a un objeto dinámicamente sin cambiar su interface .Un Decorator en cambio es más transparente a la aplicación que un Adapter, como consecuencia Soporta composición recursiva, lo cual no es posible con el patrón Adapter.
    Proxy: Define un lugar para otro objeto para controlar el acceso y no cambia su interface. 

    No hay comentarios:

    Publicar un comentario