lunes, 25 de mayo de 2009

Patron Decorator

DECORATOR


1. CLASIFICACIÓN DEL PATRÓN

Patrón Estructural.


2. INTENCIÓN

Añade responsabilidades adicionales a un objeto dinámicamente. Decoradores dan una flexible alternativa a hacer subclases para extender funcionalidad.


3. CONOCIDO TAMBIÉN

Wrapper.


4. MOTIVACIÓN

Queremos a veces agregar responsabilidades a los objetos individuales, no a una clase entera. Un juego de herramientas gráfico de la interfaz utilizador, por ejemplo, debe dejarle agregar las características tienen gusto de las fronteras o de los comportamientos como el enrollamiento a cualquier interfaz utilizador componente.

Una forma para agregar responsabilidades está con herencia. La herencia de una frontera de otra clase pone una frontera alrededor de cada caso de la subclase. Esto es inflexible, sin embargo, porque la decisión de la frontera se toma estáticamente. Un cliente no puede controlar cómo y cuándo adornar el componente con una frontera. Un acercamiento más flexible es incluir el componente en otro objeto que agregue la frontera. El objeto de cerco se llama un decorador.

El decorador se ajusta a la interfaz del componente que adorna de modo que su presencia sea transparente al componente del cliente. El decorador transmite a peticiones el componente y puede realizar acciones adicionales (tales como dibujo de una frontera) antes o después de expedición. La transparencia le deja jerarquizar a decoradores recurrentemente, de tal modo permitiendo un número ilimitado de responsabilidades agregadas.


5. POSIBLES APLICACIONES PARA EL DECORATOR

Se debe usar el patrón Decorator cuando:

· Para agregar responsabilidades a los objetos individuales dinámicamente y transparente, es decir, sin afectar a otros objetos.

· Para las responsabilidades que pueden ser retiradas.

· Cuando la extensión por subclases es impráctica. Una gran cantidad de extensiones independientes son posibles y producirían a veces una explosión de subclases para apoyar cada combinación. O una definición de clase se puede ocultar o de otra manera inasequible para las subclases.


6. ESTRUCTURA

La estructura básica que maneja el Decorator está compuesta por:


Fig. 1. Diagrama de clases del modelo de uso del Decorator.



7. PARTICIPANTES

· Component: define la interfaz para objetos que se le pueden adherir nuevas responsabilidades dinámicamente.

· ConcreteComponent: define un objeto al cual una nueva responsabilidad se le pueda dar.

· Decorator: mantiene referencia al objeto componente y define una interfaz para conformar la interfaz del componente.

· ConcreteDecorator: adhiere responsabilidades al componente.


8. COLABORACIONES

Decorator manda lo requerido a su objeto componente. Esto puede opcionalmente hacer operaciones adicionales antes y después mandar el requerimiento.


9. CONSECUENCIAS

El patrón Decorator tiene las siguientes consecuencias:

· Más flexibilidad que herencia estática. El patrón del decorador proporciona una manera más flexible de agregar responsabilidades a los objetos que puede ser tenido con herencia (múltiple) estática. Con los decoradores, las responsabilidades se pueden agregar y quitar en run-time simplemente atándolo y separando. En cambio, la herencia requiere crear una nueva clase para cada responsabilidad adicional (e.g., BorderedScrollableTextView, BorderedTextView). Esto da lugar a muchas clases y aumenta la complejidad de un sistema. Además, el abastecimiento de diverso decorador clasifica para un específico La clase componente le deja mezclar y emparejar responsabilidades.

· Evita clases característica-cargadas para arriba en la jerarquía. Ofertas del decorador un acercamiento del pagar-como-usted-ir a agregar responsabilidades. En vez de intentar a apoye todas las características previsibles en una clase compleja, adaptable, usted puede defina una clase simple y agregue la funcionalidad incremental con el decorador objetos.

· Un decorador y su componente no son idénticos. Un decorador actúa como recinto transparente. Pero desde un punto de vista de la identidad del objeto, un componente adornado no es idéntico al componente sí mismo. Por lo tanto usted no debe confiar en identidad del objeto cuando usted utiliza a decoradores.

· Porciones de pequeños objetos. Un diseño que utiliza al decorador da lugar a menudo a los sistemas integrados por las porciones de pequeños objetos que todo idéntico. Los objetos diferencian solamente de la manera que se interconectan, no en su clase o en el valor de sus variables. Aunque estos sistemas sean fáciles de modificar para requisitos particulares por los que los entiendan, pueden ser duros de aprender y de eliminar errores.


10. IMPLEMENTACIÓN

Para la implementación del Decorator es recomendable usar algunas “técnicas” para facilitar su uso.

· Conformidad del interfaz. Una interfaz del objeto decorador debe ajustarse a la interfaz del componente que adorna. Las clases de ConcreteDecorator deben por lo tanto heredar de una clase común (por lo menos en C++)

· Omisión de la clase abstracta del decorador. No hay ninguna necesidad de definir una clase abstracta del decorador cuando usted necesita solamente agregar una responsabilidad. Eso es a menudo el caso cuando se desea ocuparse de una jerarquía existente de la clase antes que diseñar uno de nuevo. En ese caso, usted puede combinar la responsabilidad de Decorator de peticiones de la expedición al componente en el ConcreteDecorator.

· Cambiando la piel de un objeto contra el cambio de su tripa. Podemos pensar en un decorador como piel sobre un objeto que cambie su comportamiento.


11. CÓDIGO DE EJEMPLO



class VisualComponent {

public:

VisualComponent();

virtual void Draw();

virtual void Resize();

// ...

};

class Decorator : public VisualComponent {

public:

Decorator(VisualComponent*);

virtual void Draw();

virtual void Resize();

// ...

private:

VisualComponent* _component;

};

void Decorator::Draw () {

_component->Draw();

}

void Decorator::Resize () {

_component->Resize();

}

void Window::SetContents (VisualComponent* contents) {

// ...

}

Window* window = new Window;

TextView* textView = new TextView;

window->SetContents(textView);

window->SetContents(

new BorderDecorator(

new ScrollDecorator(textView), 1

)

);



12. USOS CONOCIDOS

Muchos juegos de herramientas orientados al objeto del interfaz utilizador utilizan a decoradores para agregar adornos gráficos a los aparatos. Los ejemplos incluyen las entrevistas [LVC98, LCI+92], ET++ [WGM88], y la biblioteca de la clase de ObjectWorks \ del palique [Par90]. Más exótico los usos del decorador son el DebuggingGlyph de entrevistas y PassivityWrapper del palique de ParcPlace. Un DebuggingGlyph imprime la información de depuración antes y después de que transmite a una petición de la disposición su componente. Esta información del rastro se puede utilizar para analizar y para eliminar errores del comportamiento de la disposición de objetos en una composición compleja. El PassivityWrapper puede permitir o inhabilitar al usuario interacciones con el componente. Pero el patrón del decorador se limita de ninguna manera a los interfaces utilizador gráficos, pues el ejemplo siguiente (basado en el ET++ que fluye las clases [WGM88]) ilustra.


13. PATRONES ASOCIADOS

Adaptader: Un decorador es diferente de un adaptador en que un decorador cambia solamente las responsabilidades de un objeto, no su interfaz; un adaptador dará a objeto totalmente un nuevo interfaz.

Composite: Un decorador puede ser visto como compuesto degenerado con solamente un componente. Sin embargo, un decorador lo agrega adicional responsabilidad sin intención de agregación del objeto.

Strategy: Un decorador le deja cambiar la piel de un objeto; una estrategia le deja cambiar la tripa. Éstas son dos maneras alternativas de cambiar un objeto.


REFERENCIAS BIBLIOGRÁFICAS


Design Patterns. Elements of Reusable Object-Oriented Software - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides - Addison Wesley (GoF- Gang of Four)

Thinking in patterns in java – Bruce Eckel

Patterns in Java - Mark Grand – Wiley


No hay comentarios:

Publicar un comentario