Decorator

14
1 Patrones de diseño DECORATOR Mario Rodríguez Martín

description

Descripción del patrón de diseño en la programación Orienta a Objetos "Decorator"

Transcript of Decorator

Page 1: Decorator

1

Patrones de diseño

DECORATOR

Mario Rodríguez Martín

Page 2: Decorator

2

IntroducciónTambién conocido como Wrapper.

Propósito Estructural.

Ámbito Objeto.

Motivación A veces se desea adicionar responsabilidades a un objeto, pero no a toda la clase.

Las responsabilidades se pueden adicionar por medio de los mecanismos de Herencia, pero este mecanismo no es flexible porque la responsabilidad es adicionada estáticamente. La solución flexible es la de rodear el objeto con otro objeto que es el que adiciona la nueva responsabilidad. Este nuevo objeto es el Decorator.

AplicabilidadEl Decorator se debe usar para:    Adicionar responsabilidades a objetos individuales dinámicamente sin afectar otros

objetos. Para agregar responsabilidades que pueden ser retiradas. Cuando no es práctico adicionar responsabilidades por medio de la herencia.

Page 3: Decorator

3

Participantes y estructura

Componente: Interfaz común a todas las clases susceptibles de ser ampliadas con el Decorador.

ComponenteConcreto: Son las clases cuya funcionalidad se puede extender y en las que se delega en última instancia para realizar las operaciones propias de la clase.

Page 4: Decorator

4

Participantes y estructura

Decorador: Clase abstracta que declara la estructura común a todos los Decoradores y declara (o implementa, según sea el caso) la responsabilidad de mantener una referencia al objeto que se extiende. Es posible que sobrecargue todos los métodos de la clase Componente con llamadas al componente concreto, de forma que aquellos métodos cuya funcionalidad no se extiende simplemente llaman a los originales.

DecoradorConcreto1 y DecoradorConcreto2: Son clases concretas que heredan de Decorador e implementan las extensiones de funcionalidad de la clase original ComponenteConcreto.

Page 5: Decorator

5

Colaboraciones

Page 6: Decorator

6

Problema que soluciona (Ejemplo)

Supongamos que tenemos una clase existente Ventana y queremos añadirle funcionalidad para que muestre un borde alrededor. Podemos crear una subclase VentanaConBorde que herede de Ventana.

Hasta aquí todo bien, pero supongamos que surge la necesidad de crear una ventana que muestre un pequeño botón de ayuda con un signo de interrogación (?) en su parte superior. Entonces tenemos las siguientes opciones:

Crear otra subclase de Ventana: VentanaConBotónDeAyuda. Problema: No cubre la necesidad de tener ventanas con bordes y botón de ayuda a la vez.

Crear una subclase de VentanaConBorde: VentanaConBordeYBotonDeAyuda. Problema: No tenemos una ventana con botón de ayuda y sin borde.

Crear clases para todas las combinaciones posibles de funcionalidades. Problema: Con este ejemplo tendríamos cuatro clases: Ventana, VentanaConBorde, VentanaConBotonDeAyuda y VentanaConBordeYBotonDeAyuda; con tres funcionalidades tendríamos ocho clases y con cuatro, ¡dieciséis!. Para n funcionalidades se necesitan 2n clases.

Page 7: Decorator

7

Implementación (Ejemplo) El patrón Decorator soluciona este problema de una manera mucho más sencilla y extensible. Se crea a partir de Ventana la subclase abstracta VentanaDecorador y, heredando de ella,

BordeDecorador y BotonDeAyudaDecorador. VentanaDecorador encapsula el comportamiento de Ventana y utiliza composición recursiva para que sea posible añadir tantas "capas" de Decorators como se desee. Podemos crear tantos Decoradores como queramos heredando de VentanaDecorador.

Page 8: Decorator

8

Codificación: Ejemplo (I)// Interfaz Ventana

public interface Ventana {

public void dibujar(); // dibuja la ventana

public String getDescripcion(); // devuelve la descripción de la ventana

}

// Implementacion de una ventana concreta

public class VentanaConcreta implements Ventana {

public void dibujar() {

// dibujamos la ventana

}

public String getDescripcion() {

return “ventana simple”;

}

}

Page 9: Decorator

9

Codificación: Ejemplo (II)// Clase abstracta VentanaDecorador – implementa a la clase Ventana

public abstract class VentanaDecorador implements Ventana {

protected Ventana decoradorVentana;

public VentanaDecorador (Ventana decVentana) { this.decoradorVentana = decVentana;

}

}

// Añadimos funcionalidades a la ventana

public class BordeDecorador extends VentanaDecorador {

public BordeDecorador (Ventana decoradorVentana) { super(decoradorVentana);

}

public void dibujar() {

dibujarBorde();

decoradorVentana.dibujar();

}

Page 10: Decorator

10

Codificación: Ejemplo (III)private void dibujarBorde() {

// dibujamos el borde de la ventana

}

public String getDescripcion() {

return decoradorVentana.getDescripcion() + ", con borde";

}

}

public class BotonAyudaDecorador extends VentanaDecorador {

public BotonAyudaDecorador (Ventana decoradorVentana) { super(decoradorVentana);

}

public void dibujar() {

dibujarBotonAyuda();

decoradorVentana.dibujar();

}

Page 11: Decorator

11

Codificación: Ejemplo (y IV)private void dibujarBotonAyuda() {

// dibujamos el botón de ayuda

}

public String getDescripcion() {

return decoradorVentana.getDescripcion() + ", con botón de ayuda";

}

}

public class VentanaDecoradorTest {

public static void main(String[] args) {

Ventana decoradorVentana = new BotonAyudaDecorador ( new BordeDecorador(new VentanaConcreta()));

System.out.println(decoradorVentana.getDescripcion());

}

}

Page 12: Decorator

12

Reglas Implica utilizarlo si…

una jerarquía de clases tiene muchos niveles.

No se cumple si…entre una interfaz y su implementación no hay una abstracción.

Page 13: Decorator

13

Patrones relacionados Adapter

Composite

Strategy

Page 14: Decorator

14

Ventajas del patrón Decorator

Más flexible que la herencia: responsabilidades pueden añadirse y eliminarse en tiempo de ejecución.

Diferentes decoradores pueden ser conectados a un mismo objeto. Reduce el número de propiedades en las clases de la parte alta de la

jerarquía. Es simple añadir nuevos decoradores de forma independiente a las clases

que extienden. Un objeto decorador tiene diferente OID (identificador único que

proporciona el sistema) que el objeto que decora.

Sistemas con muchos y pequeños objetos.