Chain
of Responsibility (Cadena de
responsabilidad): Permite establecer la línea que deben llevar los mensajes
para que los objetos realicen la tarea indicada.
El patrón de diseño
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.
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.
Estructura
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.
Las ventajas de este patrón son:
- 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.
Implementación
- Implementación de la cadena sucesora. Hay dos formas posibles de implementarla:
- Definir nuevos enlaces (normalmente en el Manejador, pero también podría ser en los objetos ManejadorConcreto).
- Usar enlaces existentes (otras asociaciones existentes). Por ejemplo, en el patrón Composición puede existir ya un enlace al padre que puede utilizarse para definir la cadena de responsabilidad sin necesidad de añadir otra asociación.
- Conexión de los sucesores. Si no hay referencias preexistentes para definir una cadena, entonces tendremos que introducirlas nosotros mismos. En este caso, el Manejador define la interfaz y además, se encarga de mantener el sucesor. Esto permite que el manejador proporcione una implementación predeterminada de ManejarPetición que reenvíe la petición al sucesor (si hay alguno). Si una subclase de ManejadorConcreto no está intersada en dicha petición, no tiene que redefinir la operación de reenvío.
- Representación de peticiones. Hay varias opciones para representar las peticiones:
- Una petición es una invocación a una operación insertada en el código. Esto resulta conveniente y seguro, pero sólo se pueden reenviar el conjunto prefijado de peticiones que define la clase Manejador.
- Una única función manejadora que reciba un código de petición como parámetro. Esto permite un número arbitrario de peticiones pero emisor y receptor deben ponerse de acuerdo sobre cómo codificarse la petición
Command (Orden): Encapsula una operación en un objeto,
permitiendo ejecutar dicha operación sin necesidad de conocer el contenido de
la misma.
Intención
Este
patrón permite solicitar una operación a un objeto sin conocer realmente el
contenido de esta operación, ni el receptor real de la misma. Para ello se
encapsula la petición como un objeto, con lo que además se facilita la
parametrización de los métodos.
Propósito
Encapsula un mensaje como un objeto, con lo que permite
gestionar colas o registro de mensaje y deshacer operaciones.
Soportar
restaurar el estado a partir de un momento dado.
Ofrecer
una interfaz común que permita invocar las acciones de forma uniforme y
extender el sistema con nuevas acciones de forma más sencilla.
Motivo
El
concepto de "orden" puede ser ambiguo y complejo en los sistemas
actuales y al mismo tiempo muy extendido: intérpretes de órdenes del sistema
operativo, lenguajes de macros de paquetes ofimáticos, gestores de bases de
datos, protocolos de servidores de Internet, etc.
Este patrón presenta una forma sencilla y versátil de
implementar un sistema basado en comandos facilitándose su uso y ampliación.
Aplicaciones
- Facilitar
la parametrización de las acciones a realizar.
- Independizar el momento de petición del de ejecución.
Implementar CallBacks, especificando que órdenes queremos
que se ejecuten en ciertas situaciones de otras órdenes. Es decir, un parámetro
de una orden puede ser otra orden a ejecutar.
- Soportar el "deshacer".
- Desarrollar sistemas utilizando órdenes de alto nivel
que se construyen con operaciones sencillas (primitivas).
Estructura
Interpreter (Intérprete): Dado un lenguaje, define una gramática para dicho lenguaje, así como las herramientas necesarias para interpretarlo.
El interpreter es un patrón de diseño que, dado un lenguaje, define una representación para su gramática junto con un intérprete del lenguaje.
Se usa para definir un lenguaje para representar expresiones regulares que representen cadenas a buscar dentro de otras cadenas. Además, en general, para definir un lenguaje que permita representar las distintas instancias de una familia de problemas.
Motivación
Existen problemas particulares que se pueden expresar en función de algún Lenguaje.A veces es conveniente representar un lenguaje como palabras de algún lenguaje sencillo, como por ejemplo, evaluar expresiones booleanas.
El patrón Interpreter describe como definir una gramática, como representar palabras del lenguaje y como interpretarlas.
Participantes
• Cliente: Construye el árbol sintáctico abstracto de expresiones no terminales, e instancias de la clase TerminalExpresion. Luego inicializa el contexto e invoca al Interpretador.
• AbstractExpresion: Es la clase abstracta a través de la cual el cliente interactúa con las expresiones.
• TerminalExpresion: La implementación de la clase abstracta AbstractExpresion para nodos terminales en la gramática y el árbol de sintaxis.
• NonTerminalExpression: Es otra implementación de la clase abstracta para nodos no terminales de la gramática y el árbol de sintaxis. Mantiene una referencia a la siguiente expresión e invoca el método interpret en cada uno de sus hijos.
• Context: El contenedor de la información que se necesita en distintos lugares del interprete. Puede servir como un canal de comunicación entre distintas instancias de Expression.
Aplicabilidad
• Se utiliza cuando hay un lenguaje que representar cuyas sentencias se pueden representar como árboles
• La gramática es simple, de lo contrario la jerarquía de clases resulta demasiado grande y compleja
• La eficiencia no es un problema crítico
• Se obtienen soluciones más eficientes utilizando otras representaciones en lugar de árboles de análisis, como, por ejemplo, máquinas de estados (aunque éstas se pueden generar a partir de árboles construidos con este patrón)
Consecuencias
• Es fácil cambiar y ampliar la gramática.
• Resulta fácil implementarla.
• Las gramáticas complejas son difíciles de mantener.
• Añadir nuevos modos de interpretar expresiones.
Estructura


Este patrón, recibe conjuntos de objetos.y entonces pasa cualquier solicitud de un objeto a otro hasta que se alcanza uno capaz de administrarla. El número y tipo de objetos " manejador " no es conocido en primera instancia, ya que ellos pueden ser configurados dinámicamente.
ResponderEliminarEjemplo :
Existe un potencialmente variable número de "manejadores", "elementos de procesamiento" o "nodos" y una gran cantidad de peticiones que deben ser manejadas.
la ventaja mas notable de Un patrón de diseño resulta ser una solución a un problema de diseño. y que debe ser reutilizable, lo que significa que es aplicable a diferentes problemas de diseño en distintas circunstancias.
ResponderEliminarEl patrón es utilizado a menudo en el contexto de las interfaces gráficas del usuario, hay más de un objeto que puede manejar una petición, reduce el acoplamiento. simplifica las conexionares entre objetos.
ResponderEliminarLa importancia de la reutilización de los patrones de diseño no es despreciable, ya que ésta nos provee de numerosas ventajas: reduce los esfuerzos de desarrollo y mantenimiento, mejora la seguridad informática, eficiencia y consistencia de nuestros diseños, y nos proporciona un considerable ahorro en la inversión.
ResponderEliminarPodemos concluir que un patrón de diseño es una solución a un problema en un contexto
ResponderEliminar