lunes, 25 de mayo de 2009

Chain of Responsibility

Nombre del patrón
Chain of Responsibility (Cadena de Responsabilidades)

Clasificación del patrón
Comportamental.

Intención
Evita acoplar el emisor de una petición con el receptor, dando a más de un objeto la posibilidad de responder a la petición. Encadena los objetos receptores y pasa la petición a través de la cadena hasta que es procesada por algún objeto

Motivación
La idea del patrón es desacoplar a los emisores de los receptores, dándole a varios objetos la posibilidad de tratar una petición. La petición se pasa por una cadena de objetos hasta que uno de ellos la procesa.
EL primer objeto en la cadena recibe la solicitud y, o se ocupa de ella o la envía al siguiente candidato de la cadena, que hace lo mismo. El objeto que hace la solicitud no tiene conocimiento explicito de quien se hará cargo de esta, se dice que la petición tiene un receptor implícito.
Pretendemos dar un mayor detalle y especificación a las peticiones generadas. Las peticiones serán filtradas por todos los receptores a medida que se van generando los resultados esperados.

Aplicabilidad
Usamos Cadena de responsabilidades cuando:

  • Hay más de un objeto que pueden manejar una petición y esa petición no se conoce a priori, sino que se debe de determinar 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.

Estructura

Participantes
Handler
- Define una interfaz para tratar las peticiones.
- Implementa el enlace al sucesor (opcional).
ConcreteHandler
- Trata las peticiones de las que es responsable
- Puede acceder a su sucesor
- Si el ConcreteHandler puede manejar la petición, lo hace, en caso contrario la reenvía a su sucesor.
Client
- Inicializa la petición a un objeto ConcreteHandler de la cadena

Colaboraciones
Cuando un cliente envía una petición, ésta se propaga a través de la cadena hasta que un objeto ConcreteHandler se hace responsable de procesarla.

Consecuencias
Cadena de Responsabilidades tienes los siguientes beneficios e inconvenientes:

  1. Reduce el acoplamiento. Ni el receptor ni el emisor se conocen explícitamente. Un objeto sólo tiene que saber que una petición será manejada.
  2. Adiciona flexibilidad en la asignación de responsabilidades a objetos. Las responsabilidades de los mensajes pueden cambiar mediante la organización del proceso de ejecución.
  3. No se garantiza la recepción. Puesto que no existe un receptor específico para los mensajes, éstos pueden quedarse sin procesar.

Implementación
Debemos tener en cuenta al implementar este patrón:

  1. Implementar el sucesor en la cadena. Existen dos posibilidades: Definir un nuevo sucesor, usar un sucesor existente.
  2. Conexión de los sucesores. Los propios ConcreteHandler serán los que se encargarán de reenviar la petición de forma incondicional. Las referencias deberán estar definidas.
  3. Representación de las peticiones. Uso de paso de parámetros o variables mediante una función manejadora, o hacer uso de clases.

Usos Conocidos

  • Varias bibliotecas de clases usan este patrón para manejar los eventos de usuario. Aunque usan nombres distintos, la idea es siempre la misma: cuando el usuario hace clic con el ratón o pulsa una tecla, se genera un evento y se pasa a lo largo de la cadena.
  • El framework de editores gráficos Unidraw define objetos que encapsulan peticiones a los objetos Component y ComponentView. Estos objetos se estructuran jerárquicamente, así pueden reenviar interpretaciones de órdenes a su padre, quien a su vez puede reenviarlas, formando una cadena de responsabilidad.
  • ET++ usa una cadena de responsabilidad para tratar la actualización de gráficos. Un objeto gráfico llama a una operación cada vez que quiere actualizarse, pero el objeto no sabe lo suficiente sobre su contexto, por lo tanto la operación debe reenviar la petición.

Patrones relacionados
El patrón Cadena de Responsabilidad se suele aplicar junto con el patrón Composite. En él, los padres de los componentes pueden actuar como sucesores.

Referencias Bibliográficas
Design Patterns Elements of Reusable Object-Oriented Software, GoF.
http://kybele.escet.urjc.es/documentos/SI/Patrones/05_Chain.ppt
http://dmi.uib.es/~yuhua/APOO07-08/Presentation/ChRespons.pdf

No hay comentarios:

Publicar un comentario