RSS

GoF – Patrones de diseño (XI): Decorator

08 Ene

El siguiente patrón de diseño que vamos a ver es el patrón Decorator. Dicho patrón nos permitirá añadir funcionalidades o responsabilidades a un objeto de forma dinámica. Este patrón nos provee de una alternativa muy flexible a la creación de subclases para extender funcionalidades. Esto nos permitirá, en tiempo de ejecución, añadir esta funcionalidad o responsabilidad extra que necesita nuestro objeto. esto se podría hacer a través de la herencia pero no sería lo suficientemente flexible ya que de esta forma serían añadidas de forma estática. En vez de esto, nuestro objeto decorator rodeará al objeto inicial añadiendo estás responsabilidades o funcionalidades. Se hace referencia muchas veces a este patrón como Wrapper. Estoy seguro que este nombre si que lo habréis escuchado muchas veces con anterioridad.

Este patrón lo podemos aplicar para:

  • Añadir responsabilidades a un objeto individual de forma dinámica y transparente sin afectar a otros objetos.
  • Responsabilidades que pueden ser eliminadas de un objeto.
  • Cuando la extensión a través de la herencia no es viable. Por ejemplo, cuando esto provocaría una gran cantidad de subclases o la definición de la clase padre está oculta o no es accesible para realizar esta herencia.

Los elementos implicados en este patrón son:

  • Component: Define la interfaz de los objetos a los que se le podrá añadir responsabilidades dinámicamente.
  • ConcreteComponent: Define el objeto al que se le podrán añadir responsabilidades.
  • Decorator: Mantiene una referencia al objeto Component y define una interfaz que se ajusta a la interfaz de Component.
  • ConcreteDecorator: Añade las responsabilidades al componente.

El uso de este patrón, como ya hemos comentado anteriormente, nos añade mucha más flexibilidad que la herencia estática proveyéndonos de mecanismos para añadir o eliminar responsabilidades en tiempo de ejecución. Quizás el mayor problema que plantea será el de mantenibilidad del código ya que genera muchos objetos pequeños muy similares.

Pero, como siempre, lo mejor de todo es ver esto con un ejemplo. En este caso consistirá en un sistema de envío de emails corporativos.

Component:

public interface IEmail {
    public String getContents();
}

ConcreteComponent:

public class Email implements IEmail {
    private String content;

    public Email(String content) {
        this.content = content;
    }

    @Override
    public String getContents() {
        return content;
    }
}

Decorator;

public abstract class EmailDecorator implements IEmail
    IEmail originalEmail;
}

ConcreteDecorator:

public class ExternalEmailDecorator extends EmailDecorator {
    private String content;

    public ExternalEmailDecorator(IEmail basicEmail) {
        originalEmail = basicEmail;
    }

    @Override
    public String getContents() {
        content = addDisclaimer(originalEmail.getContents());
        return content;
    }

    private String addDisclaimer(String message) {
        return  message + "\n Disclaimer";
    }
}

public class SecureEmailDecorator extends EmailDecorator {
    private String content;

    public SecureEmailDecorator(IEmail basicEmail) {
        originalEmail = basicEmail;
    }

    @Override
    public String getContents() {
        content = encrypt(originalEmail.getContents());
        return content;
    }

    private String encrypt(String message) {
        return encryptedMessage;
    }
}

Main:

public class Sender() {
    public static void main(String[] args) {
        ...
    }

    public String generateEmail(IEmail email, int sentType) {
        String emailText = "";

        switch(sentType) {
            case EXTERNAL:
                EmailDecarator d1 = new ExternalEmailDecorator(email);
                emailText = d1.getContents();
                break;
            case SECURE:
                EmailDecarator d2 = new SecureEmailDecorator(email);
                emailText = d2.getContents();
                break;
            default:
                ...
        }

        return emailText;
    }
}

Como podemos ver en el ejemplo se modifican de forma fácil los emails que queremos enviar.

Otros patrones relacionados con este son: Adapter, aunque similares, se diferencian en que el Decorator modifica solo las responsabilidades del objeto, mientras que el Adapter modifica la interfaz. El Composite, ya que se puede ver al patrón Decorator como una degeneración de este con un solo componente. Strategy, es otra alternativa de cambiar un objeto.

Bueno, hasta aquí hemos llegado por hoy. Nos vemos.

Anuncios
 
Deja un comentario

Publicado por en 8 enero, 2014 en Patrones de diseño(GoF)

 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: