lunes, 25 de mayo de 2009

COMPORTAMIENTO

Chain of Responsability
intencion
establecer una cadena en un sistema, para que un mensaje pueda ser manejado en el que se recibe en primer lugar, o ser redirigido a un objeto que pueda manejarlo.

Motivacion
Considere la posibilidad de una ayuda sensible al contexto para la instalación de una interfaz gráfica de usuario. El usuario puede obtener información de ayuda en cualquier parte de la interfaz sólo haciendo clic en ella. La ayuda que se proporciona por parte depende de la interfaz que es seleccionado y su contexto, por ejemplo, un widget de botón en un cuadro de diálogo puede tener diferentes información de ayuda que un botón similar en la ventana principal. Si no hay ninguna ayuda específica existe información de que parte de la interfaz, el sistema de ayuda debe mostrar un mensaje de ayuda de carácter más general sobre el contexto inmediato-el cuadro de diálogo en su conjunto, por ejemplo. Por lo tanto, es natural de organizar la información de ayuda en función de su generalidad-desde los más específicos de la más general. Además, es claro que una solicitud de ayuda es manejado por un interfaz de usuario de varios objetos, que uno depende del contexto y la forma específica de la ayuda disponible.
El problema aquí es que el objeto que en última instancia, proporciona la ayuda no se conoce explícitamente al objeto (por ejemplo, el botón) que inicia la solicitud de ayuda. Qué necesitamos es una manera de disociar el botón que inicia la solicitud de ayuda de los objetos que puedan proporcionar información de ayuda. El patrón Chain of Responsability define que sucede.
La idea de este patrón es disociar los remitentes y receptores de varios objetos, dando la oportunidad de la tramitación de una solicitud. La petición se transmite a lo largo de una cadena de
objetos hasta que uno de ellos se ocupa de ella.

Estructura

Participantes
Handler
define una interfaz para la tramitación de las solicitudes.

ConcreteHandler
se ocupa de las solicitudes es responsable.
pueden tener acceso a su sucesor.
si el ConcreteHandler puede manejar la solicitud, lo hace de otra que remite la solicitud a su sucesor.
Cliente
inicia la solicitud de ConcreteHandler un objeto en la cadena.

Consecuencias
El patron Chain Responsability ofrece una gran flexibilidad para el procesamiento de eventos de una aplicación , por que maneja la complejidad de la gestión de evento dividiendo las responsabilidades entre elementos mas simples. Esto permite que un conjunto de clases se comporte como una unidad, porque los eventos producidos en una clase pueden ser enviados a otras clases manejador o a traves del objeto compuesto.
Por supuesto, la flexibilidad que proporciona este patrón tiene un precio este patrón es difícil de desarrollar, comprobar y depurar . Conforme el direccionamiento de la cadenas hace mas complejo, hay que controlar si los eventos están siendo enviados correctamente.

Command

Intención
Encapsular un comando en un objeto de tal forma que pueda ser almacenado, pasado a métodos y devuelto igual que cualquier otro objeto.

Motivación
A veces se quiere poder enviar solicitudes a objetos sin conocer exactamente la operación solicitada ni del receptor de la solicitud. En general un objeto botón o menú ejecuta solicitudes pero la solicitud no está implementada dentro del mismo.
Una biblioteca de clases para interfaces de usuario tendrá objetos como botones y elementos
de menú responsables de realizar alguna operación en respuesta a una entrada del usuario.

Estructura

Participantes

Command
Declara la interface para la ejecucion de la operacion

ConcreteCommand
Define la relación entre el objeto Receiver y una acción
Implemeta Execute() al invocar las operaciones correspondientes en Receiver
Client
Crea un objeto ConcreteCommand y lo relaciona con su Receiver
Invoker
Le hace solicitudes al objeto Command
Receiver
Sabe como ejecutar las operaciones asociadas a la solicitud. Cualquier clase puede ser receptora.

Consecuencias

El patron Command ofrrece flexibilidad de distintas formas:
desacopla la fuente o el disparador del evento del objeto que tiene el conocimiento para ejecutar la tarea.
Comparte instancias de Command entre distintos objetos.
Permite reemplazar objetos Command y/o Receriver en tiempo de ejecución.
Hace que los comandos sean objetos normales, teniendo todas las propiedades usuales de los objetos.
Facilita la introducción de nuevos comandos; tan solo escriba otra implementación de la interfaz e introduzca la en la aplicación.


Interpreter
Intencion
Dado un Lenguaje, definir la representación de una gramática y un interpretador, que pueda computar entradas de ese Lenguaje.

Motivación
Usamos las expresiones regulares como un estándar para especificar patrones de cadenas. En lugar de construir algoritmos personalizados para que coincida con patrón contra las cuerdas, algoritmos de búsqueda pueden interpretar una expresión regular que especifica un conjunto de cadenas de igualar.
El patrón de interpretación se describe cómo definir una gramática simple para las lenguas, representan frases en la lengua, e interpretar las sentencias.
Por ejemplo, la siguiente gramática define las expresiones regulares:
Expresión:: = literal | alternancia | secuencia | repetición | '(' expresión ')'
Alternancia:: = expresión '|' expresión
Secuencia:: = expresión 'y' expresión
Repetición:: = expresión '*'
Literal:: = 'a' | 'b' | 'c' | ... ( 'a' | 'b' | 'c' | ... *)
Expresión es el símbolo de inicio y literal es un símbolo terminal de la definición de palabras sencillas.

El intérprete utiliza patrón cinco clases para representar a la gramática: una clase abstracta RegularExpression y sus cuatro subclases LiteralExpression, AlternationExpression, SequenceExpression y RepetitionExpression.

Estructura

Participantes
AbstractExpression
Se declara una operación de resumen Interpretar que es común a todos los nodos del árbol de sintaxis abstracta.
TerminalExpression
Ejecuta una operación Interpretar símbolos asociados con la terminal en la gramática.
Una instancia se requiere para cada símbolo terminal en una frase.
NonterminalExpression
Una de esas clases es necesaria para cada regla R:: = R1 R2 ... Rn en la gramática.
Mantiene el tipo de variables de instancia AbstractExpression para cada uno de los símbolos a través de R1 Rn.
Ejecuta una operación para nonterminal Interpretar símbolos de la gramática. Interpretar normalmente se llama a sí mismo recursivamente sobre las variables que representan a través de R1 Rn.
Contexto
Que contiene información global para el intérprete.
Cliente
Se basa (o se da) una sintaxis abstracta que representa un árbol en el idioma en que se define la gramática. El árbol de sintaxis abstracta se monta a partir de las instancias de la expresión y Terminal NonterminalExpression clases.
Interpretar o invoca la operación.

Consecuencias
Gramáticas Fáciles de cambiar y extender.
Fácil Implementación.
Gramáticas Complejas son difíciles de Mantener.
Agregar nuevas formas de interpretar las cosas es sencillo.

Iterator

Intención
Proporciona una forma coherente de acceder secuencialmente a los elementos de una colección, independientemente del tipo de colección subyacente.

Motivación
Una colección de objetos, tal como una lista deberían proveer una forma o camino de acceso a sus elementos sin exponer su representación interna.
Por otra parte, se podría necesitar también recorrer la lista de diferentes formas, dependiendo del problema al que se le deba dar solución. Pero probablemente no se quiera llenar la “interface Lista” con operaciones que recorran sus elementos en distintas direcciones. También se podría tener más de un recorrido pendiente por recorrer en la misma lista.
El patrón de diseño ITERATOR permite resolver los problemas anteriormente planteados. La idea principal de este patrón es tomar la responsabilidad de acceso y recorrido de los objetos de una lista, agregando a esta última un objeto de tipo Iterator.
La Clase Iterator define una interface que permite acceder a los elementos de una lista. Un Objeto de tipo Iterator es el encargado de ir guardando el recorrido del elemento corriente, es decir, conoce los elementos que ya se han recorrido.


Estructura

Participantes
Iterator
define una interface de acceso y recorrido de los elementos de una lista.
ConcreteIterator
implementa la interface Iterator y mantiene o guarda el recorrido del ítem corriente
Aggregate
define una interface que permite crear objetos de tipo Iterator.
ConcreteAggregate
implementa la interface de creación de objetos Iterator y retorna una instancia apropiada de la clase ConcreteIterator

Consecuencias
Este patrón tiene tres consecuencias importantes:
Soporta variaciones en el recorrido de una colección, puesto que estructuras complejas pueden requerir recorridos en muchas formas. Los iteradores hacen fácil cambiar el algoritmo de recorrido, con sólo reemplazar la instancia del iterador a una diferente.
Los iteradores simplifican la interfaz de las colecciones, ya que la interfaz de los recorridos se encuentra en los iteradores y no en la clase que corresponde a la estructura en cuestión.
Más de un recorrido puede estar pendiente en una colección, puesto que cada iterador mantiene la pista de su recorrido. Por lo tanto, se puede tener más de un recorrido en progreso al mismo tiempo.

Mediator
Intención
Simplificar la comunicación entre los objetos de un sistema introduciendo un único objeto que gestiona la distribución de mensajes entre los otros.

Motivación
Cuando muchos objetos interactúan con otros objetos, se puede formar una estructura muy compleja, con objetos con muchas conexiones con otros objetos. En un caso extremo cada objeto puede conocer a todos los demás objetos. Para evitar esto el patrón Mediator encapsula el comportamiento de todo un conjunto de objetos en un solo objeto.

Estructura

Participantes
Mediator
Define una interface para comunicarse con los objetos colegas.
ConcreteMediator
Implementa el comportamiento cooperativo entre los colegas (como se comunican entre ellos). Además los conoce y mantiene.
Colleagues
Cada colega conoce su mediador, y usa a este para comunicarse con otros colegas.

Consecuencias

El patrón Mediator tiene los siguientes beneficios y desventajas:
Desacopla a los colegas: el patrón Mediator promueve bajar el acoplamiento entre colegas. Se puede variar y reusar colegas y mediadores independientemente
Simplifica la comunicación entre objetos: Los objetos que se comunican de la forma "muchos a muchos" puede ser remplazada por una forma "uno a muchos" que es menos compleja y más elegante. Además esta forma de comunicación es más fácil de entender.
Abstrae como los objetos cooperan: Haciendo a la mediación un concepto independiente y encapsulandolo en un objeto permite enfocar como los objetos interactúan. Esto ayuda a clarificar como los objetos se relacionan en un sistema.
Centraliza el control: El mediador es el que se encarga de comunicar a los colegas, este puede ser muy complejo, difícil de entender y modificar


Memento
Intención
Guardar una el estado de un objeto, de forma que pueda ser devuelto a su estado original sin revelar su contenido al resto del mundo.

Motivación

Muchas veces es necesario guardar el estado interno de un objeto. Esto debido a que tiempo
después, se necesita restaurar el estado del objeto, al que previamente se ha guardado.
Consideremos por ejemplo una aplicación de composición de figuras geométricas, donde
el usuario hace sucesivas modificaciones a una composición, graficando nuevas líneas, círculos y rectángulos. Después de cierto tiempo, el usuario logra una composición “casi perfecta”, pero decide alcanzar la perfección, así que pinta una línea y esta no le sale como él esperaba. Definitivamente el usuario quisiera regresar al instante en que su “creación” era una obra de arte. Para dar solución a este problema, antes de que el usuario agregue una
nueva figura geométrica a la composición, se debería guardar el estado de la composición y entonces siempre se tendría la posibilidad de regresar hacia atrás y restaurar la composición a su estado anterior.
Para lograr esto, sería necesario guardar la lista de figuras geométricas y el orden en que se encuentran en la composición, con información específica de cada una de ellas. En el caso de un círculo tendríamos que guardar la posición (x, y), el radio, color y relleno, para un rectángulo la posición (x, y), el ancho, el largo, color y relleno. Para lograr esto tenemos tres alternativas: la primera alternativa consiste en obtener la lista de figuras de la composición y
obtener su estado, esto sería muy complejo y además va en contra del principio de encapsulamiento; la segunda alternativa, es que la composición se encargue de ir guardando su estado interno cada vez, esta no es una buena alternativa, la clase sería muy compleja y estaría asumiendo responsabilidades que no le corresponden; la tercera alternativa es la mejor, composición (Originator) crea un objeto (Memento) y almacena su estado interno en él, la aplicación (Caretaker) mantiene una lista de los objetos (Memento), de tal manera que
cuando el usuario realice una operación de “deshacer”, la aplicación restaure el estado de la composición (Originator), con lo almacenado por el objeto Memento.

Estructura

Participantes
Memento
Almacena el estado interno de un objeto Originator. El Memento puede almacenar mucho o parte del estado interno de Originator.
Tiene dos interfaces. Una para Caretaker, que le permite manipular el Memento únicamente para pasarlo a otros objetos.
La otra interfaz sirve para que Originator pueda almacenar/restaurar su estado interno, sólo Originator puede acceder a esta interfaz, al menos en teoría.
Originator
Originator crea un objeto Memento conteniendo una fotografía de su estado interno.
Originator usa a Memento para restaurar su estado interno.
Caretaker
Es responsable por mantener a salvo a Memento.
No opera o examina el contenido de Memento.

Consecuencias
• Originator crea un Memento y el mismo almacena su estado interno, de esta manera no es necesario exponer el estado interno como atributos de acceso público, preservando así la encapsulación.
• Si Originator tendría que de almacenar y mantener a salvo una o muchas copias de su estado interno, sus responsabilidades crecerían y serían más complejas, se desviaría de su propósito disminuyendo la coherencia. Usar Mementos hace que Originator sea mucho más sencillo y coherente.
• El uso frecuente de Mementos para almacenar estados internos de gran tamaño, podría resultar costoso y perjudicar el rendimiento del sistema.
• Caretaker al no conocer detalles del estado interno de Originator, no tiene idea de cuanto espacio y tiempo se necesita para almacenar el estado interno de Originator en un Memento y restaurar su estado interno a partir de un Memento. Por lo que no puede hacer predicciones de tiempo ni de espacio.
• Memento debería proporcionar una interfaz privada, a la que sólo Originator puede acceder. Esta interfaz incluye la creación, el almacenamiento y recuperación del estado interno de Originator. Además una interfaz pública que permita la destrucción de Memento.


Observer

Intención
proporcionar a los componentes una forma flexible de enviar mensajes de difusión a los receptores interesados.

Motivación

Al dividir sistema en colección de clases cooperantes:
• Necesidad de mantener la consistencia entre los objetos
relacionados.
• Evitar fuerte acoplamiento entre clases.
Las clases que definen los datos de las aplicaciones y las
representaciones pueden reutilizarse de forma independiente.
Objetos participantes: sujeto y observadores.
Cada vez que el sujeto cambia su estado se notifica a todos
sus observadores.

Estructura


Participantes
Subject
Conoce a sus observadores. Cualquier número de Observación de los objetos puede observar un objeto.
Provee una interfaz para conectar y desconectar de Observación de los objetos.
Observer
Define una interfaz para la actualización de los objetos que deben ser notificados de los cambios en un tema.
ConcreteSubject
Las tiendas estatales de interés para ConcreteObserver objetos.
Envía una notificación a sus observadores cuando su estado cambia.
ConcreteObserver
Mantiene una referencia a un objeto ConcreteSubject.
Las tiendas del Estado que debe mantenerse en consonancia con la del sujeto.
Se aplica la actualización de la interfaz de Observadores para mantener su estado en consonancia con la del sujeto.

Consecuensias
Ventajas:
Permite modificar las clases subjects y las observers independientemente. Se pueden rehusar clases subjects sin rehusar sus clases observers.
Permite añadir nuevas clases observers a una clase subject que ya tenía asociadas unas clases observers sin modificar la clase subject o alguno de esas clases observers que ya tenía.
Permite que dos capas de abstracción de diferentes niveles de abstracción se puedan comunicar entre sí sin romper esa división en capas de abstracción. Por ejemplo, en el caso de las capas de Presentación y Dominio.
Permite comunicación broadcast, es decir, un objeto subject envía su notificación a todos los objetos observers que lo estén observando sin enviárselo a ningún observer en concreto (el mensaje no tiene un destinatario concreto). Todos los observers reciben el mensaje y deciden si hacerle caso ó ignorarlo.
Desventajas:
El protocolo de comunicación entre los objetos subject y sus objetos observers es muy pobre: el evento siempre es que se ha producido algún cambio en el estado del objeto subject, el mensaje no indica el destinatario (siempre es broadcast) y tampoco indica qué es lo que ha cambiado en el objeto subject (y, entonces, son sus objetos observers los que tienen que deducir qué es lo que ha cambiado en el objeto subject sin ayuda de éste, si así lo desean; lo que puede introducir gran complejidad computacional en los observers).
Aumenta el número de clases necesarias para implementar la aplicación y disminuye la comprensibilidad de ésta.
Los observers dependen del subject al que observan, pues lo conocen (hacen referencia a él), por lo que cambios en la clase del subject pueden provocar cambios en las de los observers.


State
intención
Cambiar fácilmente el comportamiento de un objeto en tiempo de ejecución.

Motivación

El patrón State está motivado por aquellas clases que, según su estado actual varía su comportamiento ante los diferentes mensajes. Como ejemplo se toma una clase TCPConection la que representa una conexión de red, un objeto de esta clase tendrá diferentes respuestas según su estado (Listening, Close o Established). Por ejemplo una llamada al método Open de un objeto de la clase TCPConection diferirá su comportamiento si la conexión se encuentra en Close o en Established.

Estructura

Participantes
• Context
Este integrante define la interfaz con el cliente. Mantiene una instancia de ConcreteState (Estado Concreto) que define su estado actual
State
Define una interfaz para el encapsulamiento de la responsabilidades asociadas con un estado particular de Context.
Subclase ConcreteState
Cada una de estas subclases implementa el comportamiento o responsabilidad de Context.
El Contexto delega el estado específico al objeto ConcreteState actual Un objeto Context puede pasarse a sí mismo como parámetro hacia un objeto State. De esta manera la clase State puede acceder al contexto si fuese necesario. Context es la interfaz principal para el cliente. El cliente puede configurar un contexto con los objetos State. Una vez hecho esto, los clientes no tendrán que tratar con los objetos State directamente. Tanto el objeto Context como los objetos de ConcreteState pueden decidir el cambio de estado

Consecuencias
Se encuentran las siguientes ventajas:
Se localizan fácilmente las responsabilidades de los estados específicos, dado que se encuentran en las clases que corresponden a cada estado. Esto brinda una mayor claridad en el desarrollo y el mantenimiento posterior. Esta facilidad la brinda el hecho que los diferentes estados están representados por un único atributo (state) y no envueltos en diferentes variables y grandes condicionales.
Hace los cambios de estado explícitos puesto que en otros tipos de implementación los estados se cambian modificando valores en variables, mientras que aquí al estar representado cada estado.
Los objetos State pueden ser compartidos si no contienen variables de instancia, esto se puede lograr si el estado que representan esta enteramente codificado en su tipo. Cuando se hace esto estos estados son Flyweights sin estado intrínseco.
Facilita la ampliación de estados
Permite a un objeto cambiar de clase en tiempo de ejecución dado que al cambiar sus responsabilidades por las de otro objeto de otra clase la herencia y responsabilidades del primero han cambiado por las del segundo.
Se encuentran la siguiente desventaja:
Se incrementa el número de subclases.


Strategy
Intención
Definir una familia de algoritmos, encapsularlos y hacerlos intercambiables

Motivación
Muchas clases relacionadas difieren sólo en su comportamiento
Se necesitan distintas variantes del mismo algoritmo
Una clase define muchos comportamientos

Estructura

Participantes
Strategy
Declara una interfaz común a todos los algoritmos soportados
ConcreteStrategy
Implementa el algoritmo que que usa la interfaz strategy.
Context
Se configuran con un objeto ConcreteStrategy
Mantiene una referencia a un objeto Strategy
Puede definir una interfaz que permite acceder a sus datos

Consecuencias
Es una alternativa a la herencia
Eliminan estructuras condicionales
Selección de implementaciones.


Template Method

Intención
Usando el Template Method, se define una estructura de herencia en la cual la superclase sirve de plantilla de los métodos en las subclases. Una de las ventajas de este método es que evita la repetición de código, por tanto la aparición de errores.

Motivación
Este patrón se vuelve de especial utilidad cuando es necesario realizar un algoritmo que sea común para muchas clases, pero con pequeñas variaciones entre una y otras.

Estructura

Participantes
AbstractClass
Resumen define las operaciones primitivas que concretesubclasses definir para la aplicación de medidas de un algoritmo.
Aplica un método de definición de la plantilla de un esqueleto algoritmo. La plantilla llamadas a los métodos primitivos de operaciones, así como operaciones definidas en AbstractClass o los de otros objetos.
ConcreteClass
se aplica la primitiva para llevar a cabo operaciones específicas de la subclase de los pasos del algoritmo.

Consecuencias
Facilita la reutilización de código. Sin el método plantilla, el código se duplica en muchas subclases. Esta ventaja hace que el patrón sea fundamental en muchos frameworks. El uso del patrón implica que la estructura completa puede ser proporcionada por el Framework, solo tendrá que redefinir unos pocos métodos para poder ser utilizado.
Si el método plantilla llama a demasiados métodos abstractos, se cansara pronto de utilizar AbstractClass como superclase. Es mejor hacer que el método plantilla llame a un numero limitado de métodos abstractos.


Visitor
Intención
Representa una operación que se realiza sobre los elementos que conforman la estructura de un objeto. Visitor permite definir nuevas operaciones sin cambiar las clases de los elementos en los que opera.

Motivación

Un compilador representa los programas como árboles de sintaxis abstracta, sobre los que ejecuta operaciones
Muchas operaciones necesitan diferenciar distintos tipos de nodo en el árbol (expresiones, variables, etc.)

Estructura

Participantes
Visitor
define una operación de visita para cada clase de elemento concreto en la estructura de objetos
ConcreteVisitor
Implementa la interfaz Visitor
Cada operación implementa un fragmento de la labor global del visitor concreto, pudiendo almacenar información local
Element
define una operación accept con un visitor como argumento
ConcreteElement
implementa la operación accept
ObjectStructure
Gestiona la estructura de objetos, y puede enumerar sus elementos
Puede ser un compuesto (patrón composite) o una colección de objetos
Puede ofrecer una interfaz que permita al visitor visitar a sus elementos

Consecuencias
Facilita la definición de nuevas operaciones.
Agrupa operaciones relacionadas.
Añadir nuevas clases ConcreteElement es costoso.
Utilizar el patrón visitor si la jerarquía de clases es estable.
Permite atravesar jerarquías de objetos que no están relacionados por un padre común.
El visitor puede acumular el estado de una operación al visitar la estructura de objetos, en vez de pasarlo como argumento o usar variables globales.
Rompe la encapsulación.

No hay comentarios:

Publicar un comentario