Patrón de diseño: Chain of Responsability

Chain of Responsibility es un patrón de comportamiento que evita acoplar el emisor de una petición a su receptor dando a más de un objeto la posibilidad de responder a una petición. Para ello, se encadenan los receptores y pasa la petición a través de la cadena hasta que es procesada por algún objeto. Este patrón es utilizado a menudo en el contexto de las interfaces gráficas de usuario donde un objeto puede contener varios objetos. Según si el ambiente de ventanas genera eventos, los objetos los manejan o los pasan.

Chain Of Responsability

Chain Of Responsability

Aplicabilidad

El patrón Cadena de Responsabilidad debe usarse cuando:

  • Hay más de un objeto que puede manejar una petición, y el manejador no se conoce a priori, sino que debería determinarse automáticamente.
  • Se quiere enviar una petición a un objeto entre varios sin especificar explícitamente el receptor.
  • El conjunto de objetos que pueden tratar una petición debería ser especificado dinámicamente.

Participantes

Manejador: define una interfaz para tratar las peticiones. Opcionalmente, implementa el enlace al sucesor.
ManejadorConcreto: trata las peticiones de las que es responsable; si el ManejadorConcreto puede manejar la petición, lo hace; en caso contrario la reenvía a su sucesor.
Cliente: inicializa la petición a un Manejador Concreto de la cadena.

Consecuencias

Reduce el acoplamiento. El patrón libera a un objeto de tener que saber qué otro objeto maneja una petición. Ni el receptor ni el emisor se conocen explícitamente entre ellos, y un objeto de la cadena tampoco tiene que conocer la estructura de ésta. Por lo tanto, simplifica las interconexiones entre objetos. En vez de que los objetos mantengan referencias a todos los posibles receptores, sólo tienen una única referencia a su sucesor.

Añade flexibilidad para asignar responsabilidades a objetos. Se pueden añadir o cambiar responsabilidades entre objetos para tratar una petición modificando la cadena de ejecución en tiempo de ejecución. Esto se puede combinar con la herencia para especializar los manejadores estáticamente.

Por otra parte presenta el inconveniente de no garantizar la recepción. Dado que las peticiones no tienen un receptor explícito, no hay garantías de que sean manejadas. La petición puede alcanzar el final de la cadena sin haber sido procesada.

Patrones Relacionados

Este patrón se aplica en ocasiones con el patrón Composite. En él, los padres de los componentes pueden actuar como sucesores.

Ejemplo

En el siguiente ejemplo un objeto petición, el cual tiene dos propiedades una del tipo string que es una descripcion y otra del tipo int que simula un valor. Este objeto es pasado a la cadena de responsabilidad y dependiendo de los valores de este int lo procesará uno u otro Manejador Concreto. Para el caso de que el int sea menor que 0 el objeto que lo procesa es ManejadorConcreto1. En cambio si el int value de la petición es mayor que 0 lo procesa ManejadorConcreto2.

Manejador

public abstract class Manejador {
	protected Manejador sucesor;

	public void setSucesor(Manejador sucesor) {
		this.sucesor = sucesor;
	}

	public abstract void manejarPeticion(Peticion peticion);
}

ManejadorConcreto1

public class ManejadorConcreto1 extends Manejador{


	@Override
	public void manejarPeticion(Peticion peticion) {
		// TODO Auto-generated method stub
		if (peticion.getValue() < 0)
		{           
			System.out.println("Los valores negativos son manejados por "+this.getClass());
			System.out.println("Valores peticion : " + peticion.getDescripcion() + peticion.getValue());
		}
		else
		{
			sucesor.manejarPeticion(peticion);
		}
	}

}

ManejadorConcreto2

public class ManejadorConcreto2 extends Manejador{

	@Override
	public void manejarPeticion(Peticion peticion) {
		
		if (peticion.getValue() >= 0) { 
			System.out.println("Los valores mayores que 0 son manejados por "+this.getClass());
			System.out.println("Valores peticion : "+ peticion.getDescripcion() + peticion.getValue());
		} else {
			sucesor.manejarPeticion(peticion);
		}
		
		
	}

}

Peticion

public class Peticion {
	
	private int value;
	private String descripcion;
	
	public Peticion (String descripcion , int value){
		this.value = value;
		this.descripcion = descripcion;
	}

	public int getValue() {
		return value;
	}

	public String getDescripcion() {
		return descripcion;
	}
}

App

public class App {
	public static void main(String[] args) 
	{
		
		
		Manejador m1 = new ManejadorConcreto1();
		Manejador m2 = new ManejadorConcreto2();
		
		m1.setSucesor(m2);
		m1.manejarPeticion(new Peticion("Negativo ",-1));
		m1.manejarPeticion(new Peticion("Positivo ",0));
		m1.manejarPeticion(new Peticion("Positivo ",5));

		
		
	}
}

Si te ha servido dale a +1 para ayudarme con el posicionamiento de google, comparte por face o dale a me gusta .. en fin esas cositas al pie de la página

Anuncios

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