Decorator

1 Sinopsis

De una manera dinamica, es posible adicionar responsabilidades a un objeto

2 Contexto

3 Solucion

4 Consecuencias

5 Ejemplo

Sea una interfase que proporciona un conjunto de servicios


public interface ControladorIF  {
    ....
}
See the complete code for ControladorIF here.
public String servicio(String datos);

Una clase que implemente esta interfase puede ser:


public class ControladorUpper implements ControladorIF  {
    ....
}
See the complete code for ControladorUpper here.
public String servicio(String datos){
  return datos.toUpperCase();
}

El cliente de la clase manipula la interfase. Sin embargo, se quiere proveer una nueva clase que implemente al servicio, que ademas de convertir a mayusculas, determine la longitud de la cadena, y si supera una longitud, no la procesa y dispara una excepcion. La clase que cuida la longitud es:


public class CuidadorLongitud  {
    ....
}
See the complete code for CuidadorLongitud here.
private int _max;
public CuidadorLongitud(int max) { _max = max; }
public void cuidar(String s) { 
    if (s.length() > _max) {
      throw new RuntimeException("Longitud excedida");
    }
}

Se desea que el cliente utilice esta nueva funcion del servicio ControladorIF, para esto se define una clase abstracta.


public abstract class ControladorWrapper implements ControladorIF  {
    ....
}
See the complete code for ControladorWrapper here.
  private ControladorIF wrappee;
  public ControladorWrapper(ControladorIF wrappee) {
    this.wrappee = wrappee;
  }
  public String servicio(String datos){
     return this.wrappee.servicio(datos);
  }

Dado que es una clase abstracta, la clase concreta extiende a ControladorWrapper e incorpora a un objeto de tipo CuidadorLongitud para controlar la invocacion al metodo servicio


public class ConcretoControladorWrapper extends ControladorWrapper  {
    ....
}
See the complete code for ConcretoControladorWrapper here.
private CuidadorLongitud cuidador;
public ConcretoControladorWrapper(ControladorIF wrappee, CuidadorLongitud cuidador) {
 super(wrappee);
 this.cuidador=cuidador;
}
public String servicio(String datos){
  cuidador.cuidar(datos);
  return super.servicio(datos);
}

El cliente se resume a:


public class ClienteDecorator  {
    ....
}
See the complete code for ClienteDecorator here.
public static void main(String [] args) {
  ControladorIF ctl = new ConcretoControladorWrapper( new ControladorUpper() , 
		new CuidadorLongitud(10));
   System.out.println(ctl.servicio("gus"));
}