martes, 19 de mayo de 2009

Decorator

Nombre del patrón
Decorator

Clasificación del patrón
Estructural

Intención

Fijar responsabilidades adicionales a un objeto dinámicamente. Decorator ofrece una alternativa flexible de herencia para extender funcionalidades.

También conocido como:
Wrapper o envolvente.

Motivación
A veces queremos añadir responsabilidades a objetos individuales y no a toda la clase. Una interfaz grafica de usuario toolkit, por ejemplo, en donde se le permite añadir características como los bordes o comportamientos como el desplazamiento de cualquier componente de la interfaz del usuario.
Una forma de añadir responsabilidades es con herencia. Heredar un borde a otra clase pone un borde alrededor de cada subclase instanciada. Esto es inflexible, porque la elección del borde se hace estáticamente. Un cliente no puede controlar cómo y cuando se decora un componente del borde.
Un enfoque más flexible es incluir el componente en otro objeto que se adiciona al borde. El objeto adjuntado se llama decorador, El decorados se ajusta a la interfaz del componente que decora de modo que su presencia es transparente para el cliente de los componentes.

Aplicabilidad
Usamos decorador para:

  • Adicionar responsabilidades a objetos individuales dinámicamente sin afectar otros objetos.
  • Agregar responsabilidades que pueden ser retiradas.
  • Cuando no es práctico adicionar responsabilidades por medio de la herencia.

Estructura

Participantes

  • Component define la interfaz para los objetos que pueden tener las responsabilidades que se les añade dinámicamente.
  • ConcreteComponent define un objeto al que se le pueden añadir responsabilidades.
  • Decorator almacena una referencia a un objeto Component y define una interfaz que se ajusta a la de Component.
  • ConcreteDecorator añade responsabilidades al componente.

Colaboraciones
Decorator envía las solicitudes al objeto Component. Opcionalmente puede realizar operaciones adicionales antes y después del envió de la solicitud.

Consecuencias

  1. Más flexibilidad que la herencia estática. El patrón Decorator proporciona una forma más flexible para añadir responsabilidades a los objetos que puede hacerse con herencia estática (múltiple). Con decoradores, las responsabilidades se pueden añadir y quitar en tiempo de ejecución simplemente conectando y desconectando estos.
  2. Evita sobrecargar las partes altas de una jerarquía de clases con funcionalidades potencialmente innecesarias.
  3. En decorador y sus componentes no son idénticos. Un decorador actúa como una caja transparente, no debería confiarse de la identidad del objeto cuando se utiliza decoradores.
  4. Grupos de pequeños objetos. Un uso extensivo del patrón Decorator produce código más difícil de entender y depurar, al crear sistemas compuestos de grupos de pequeños objetos.

Implementación
Para aplicar el patrón Decorator debemos tener en cuenta:

  1. Conformación de interfaces. Un decorador de objetos de la interfaz deben ajustarse a la interfaz del componente que decora.
  2. Omitiendo la clase abstracta Decorator. No hay necesidad de definir una clase abstracta Decorator cuando solo se tenga que añadir una responsabilidad.
  3. Mantener clases Componen ligeras. Para garantizar un ajuste de interfaz, componentes y decoradores deben descender de una clase común de componentes.
  4. Cambiando la máscara de un objeto vs a cambiar su interior. Podemos pensar en un decorador como una máscara de un objeto, más que en algo que cambie su comportamiento. EL patrón Strategy es un buen ejemplo para cambiar el interior.

Usos Conocidos
Muchas de las interfaces de usuarios orientadas toolkits (herramientas) usan decoradores para añadir adornos gráficos a sus widgets (pequeñas aplicaciones)

Patrones relacionados
Adapter:
Un decorador es diferente que un adaptador, un decorador solo cambia las responsabilidades de un objeto y no su interfaz; un adaptador dará a un objeto una interfaz completamente nueva.
Composite: Un decorador puede ser visto como una forma degenerada de Composite con un solo componente. Sin embargo un decorador añade nuevas responsabilidades que no estaban destinadas al objeto por agregación.
Strategy: Un decorador cambia la mascara (apariencia) de un objeto, en Strategy se cambia su interior.

Referencias Bibliográficas
Design Patterns Elements of Reusable Object-Oriented Software, GoF. http://www.lsi.us.es/docencia/get.php?id=1379
http://www.ayc.unavarra.es/miguel.pagola/Decorador.pdf

No hay comentarios:

Publicar un comentario