Title: Patrones de diseo
1Patrones de diseño
Mario Rodríguez Martín David Sánchez
Fernández Roberto Santa Escolástica Villoria
2Introducción
- Tambié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. - Aplicabilidad
- El 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.
3Participantes 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.
4Participantes 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.
5Colaboraciones
6Problema 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 VentanaConBordeYBotonDeAy
uda con tres funcionalidades tendríamos ocho
clases y con cuatro, dieciséis!. Para n
funcionalidades se necesitan 2n clases.
7Implementació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.
8Codificació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
9Codificació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()
10Codificación Ejemplo (III)
private void dibujarBorde() // dibujamos el
borde de la ventana public String
getDescripcion() return decoradorVentana.getD
escripcion() ", con borde" public
class BotonAyudaDecorador extends
VentanaDecorador public BotonAyudaDecorador
(Ventana decoradorVentana) super(decoradorVe
ntana) public void dibujar()
dibujarBotonAyuda() decoradorVentana.dibuja
r()
11Codificación Ejemplo (y IV)
private void dibujarBotonAyuda() //
dibujamos el botón de ayuda public String
getDescripcion() return decoradorVentana.getD
escripcion() ", 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(decorad
orVentana.getDescripcion())
12Reglas
- 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.
13Patrones relacionados
- Adapter
- Composite
- Strategy
14Ventajas 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.