El patrón Cadena de Responsabilidades (Chain of Responsibility) permite que múltiples objetos tengan la oportunidad de procesar una solicitud, evitando así el acoplamiento entre el emisor y el receptor de la petición. En este patrón, los objetos se conectan formando una cadena, y la solicitud se transmite a lo largo de esta hasta que encuentra un objeto capaz de procesarla.
Ventajas:
Tanto el emisor como el receptor carecen de información explícita sobre el otro, y los objetos de la cadena no conocen la estructura completa de la misma. Esto permite simplificar la cadena de responsabilidades mediante conexiones entre objetos que solo necesitan mantener una referencia a su sucesor, sin necesidad de almacenar referencias a todos los posibles receptores. La estructura para procesar una solicitud puede modificarse o ampliarse en cualquier momento, lo que aumenta la fleexibilidad a la hora de asignar responsabilidades a los objetos.
Desventajas:
Una solicitud podría legar al final de la cadena sin ser procesada, o no recibir trataimento debido a una configuración incorrecta.
Código de cliente
Procesador p1 = new ManejadorConcreto1();
Procesador p2 = new ManejadorConcreto2();
Procesador p3 = new ManejadorConcreto3();
p1.establecerSucesor(p2); // Configurar la cadena de responsabilidad
p2.establecerSucesor(p3);
int[] peticiones = { 2, 5, 14, 20, 22, 30 };
foreach( int peticion in peticiones)
{
p1.procesarSolicitud(peticion);
}
Console.Read();
Ver códigoImplementación del patrón
abstract class Procesador
{
protected Procesador sucesor;
public void establecerSucesor(Procesador sucesor)
{
this.sucesor = sucesor;
}
public abstract void procesarSolicitud(int solicitud);
}
/// <summary>
/// Clase de manejo concreta que procesa las solicitudes asignadas, tiene acceso a su sucesor.
/// Si puede manejar la solicitud, la procesa; de lo contrario, la pasa a su sucesor.
/// </summary>
class ManejadorConcreto1 : Procesador
{
public override void procesarSolicitud(int solicitud)
{
if(solicitud >=0 && solicitud<10)
{
Console.WriteLine("{0} procesa la solicitud {1}", this.GetType().Name, solicitud);
}
else if(sucesor !=null)
{
sucesor.procesarSolicitud(solicitud);
}
}
}
class ManejadorConcreto2 : Procesador
{
public override void procesarSolicitud(int solicitud)
{
if (solicitud >= 10 && solicitud < 20)
{
Console.WriteLine("{0} procesa la solicitud {1}", this.GetType().Name, solicitud);
}
else if (sucesor != null)
{
sucesor.procesarSolicitud(solicitud);
}
}
}
class ManejadorConcreto3 : Procesador
{
public override void procesarSolicitud(int solicitud)
{
if (solicitud >= 20 && solicitud < 30)
{
Console.WriteLine("{0} procesa la solicitud {1}", this.GetType().Name, solicitud);
}
else if (sucesor != null)
{
sucesor.procesarSolicitud(solicitud);
}
}
}
Ver códigoEste patrón resuelve problemas de mantenimiento y flexibilidad causados por el uso excesivo de estructuras condicionales en el código tradicional.