Resumen de Patrones

33
Singleton El patrón de diseño singleton (instancia única) está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto. Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella. El patrón singleton se implementa creando en nuestra clase un método que crea una instancia del objeto sólo si todavía no existe alguna. Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor (con atributos como protegido o privado). La instrumentación del patrón puede ser delicada en programas con múltiples hilos de ejecución. Si dos hilos de ejecución intentan crear la instancia al mismo tiempo y esta no existe todavía, sólo uno de ellos debe lograr crear el objeto. La solución clásica para este problema es utilizar exclusión mutua en el método de creación de la clase que implementa el patrón. Las situaciones más habituales de aplicación de este patrón son aquellas en las que dicha clase controla el acceso a un recurso físico único (como puede ser el ratón o un archivo abierto en modo exclusivo) o cuando cierto tipo de datos debe estar disponible para todos los demás objetos de la aplicación.

Transcript of Resumen de Patrones

Page 1: Resumen de Patrones

Singleton

El patrón de diseño singleton (instancia única) está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.

Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.

El patrón singleton se implementa creando en nuestra clase un método que crea una instancia del objeto sólo si todavía no existe alguna. Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor (con atributos como protegido o privado).

La instrumentación del patrón puede ser delicada en programas con múltiples hilos de ejecución. Si dos hilos de ejecución intentan crear la instancia al mismo tiempo y esta no existe todavía, sólo uno de ellos debe lograr crear el objeto. La solución clásica para este problema es utilizar exclusión mutua en el método de creación de la clase que implementa el patrón.

Las situaciones más habituales de aplicación de este patrón son aquellas en las que dicha clase controla el acceso a un recurso físico único (como puede ser el ratón o un archivo abierto en modo exclusivo) o cuando cierto tipo de datos debe estar disponible para todos los demás objetos de la aplicación.

El patrón singleton provee una única instancia global gracias a que:

La propia clase es responsable de crear la única instancia. Permite el acceso global a dicha instancia mediante un método de clase. Declara el constructor de clase como privado para que no sea instanciable

directamente.

----------------------------------------------------------------------------------------------------------

Page 2: Resumen de Patrones

Mediator (patrón de diseño)

Intención

Definir un objeto que encapsule cómo interactúa un conjunto de objetos.

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.

Aplicabilidad

Usar el patrón Mediator cuando:

Un conjunto grande de objetos se comunica de una forma bien definida, pero compleja. Reutilizar un objeto se hace difícil porque se relaciona con muchos objetos. El comportamiento de muchos objetos que esta distribuido entre varias clases, puede

resumirse en una o varias por subclasificación.

Estructura

Participantes

Mediator (mediador): define una interfaz para comunicarse con los objetos colegas. ConcreteMediator ("mediador concreto"): Implementa el comportamiento cooperativo

entre los colegas (como se comunican entre ellos). Además los conoce y mantiene. Colleagues ("colegas"): Cada colega conoce su mediador, y usa a este para comunicarse

con otros colegas.

Ejemplo explicativo: El mediator es el que tiene la tarifa plana y se encarga de llamar a todos los colegas. Los colegas llaman al mediador para ahorrase unos duros en la factura

Page 3: Resumen de Patrones

Colaboraciones

Los colegas envían y reciben requerimientos (requests) de un objeto mediador. El mediador implementa como se comunican los 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 rehusar 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

-----------------------------------------------------------------------------------------------------------------------------------

Facade (patrón de diseño)

[editar] Introducción

Los patrones de diseño dan una solución probada y documentada a problemas de desarrollo de software que aparecen en un contexto similar. El patrón de diseño Fachada (Facade) es un tipo de patrón estructural.

Page 4: Resumen de Patrones

Propósito

El patrón fachada se utiliza para proporcionar una interfaz unificada de alto nivel para un conjunto de clases en un subsistema, haciéndolo más fácil de usar. Simplifica el acceso a dicho conjunto de clases, ya que el cliente sólo se comunica con ellas a través de una única interfaz.

Motivación

El patrón fachada viene motivado por la necesidad de estructurar un entorno de programación y reducir su complejidad con la división en subsistemas, minimizando las comunicaciones y dependencias entre éstos.

Consideraciones para su aplicación

Se aplicará el patrón fachada cuando se necesite proporcionar una interfaz simple para un subsistema complejo, o cuando se quiera estructurar varios subsistemas en capas, ya que las fachadas serían el punto de entrada a cada nivel. Otro escenario proclive para su aplicación surge de la necesidad de desacoplar un sistema de sus clientes y de otros subsistemas, haciéndolo más independiente, portable y reutilizable (esto es, reduciendo dependencias entre los subsistemas y los clientes).

Estructura

Se puede ver en la figura.

Participantes

Fachada (Facade): conoce qué clases del subsistema son responsables de una determinada petición, y delega esas peticiones de los clientes a los objetos apropiados del subsistema.

Subclases (ModuleA, ModuleB, ModuleC...): implementan la funcionalidad del subsistema. Realizan el trabajo solicitado por la fachada. No conocen la existencia de la fachada.

Colaboraciones

Los clientes se comunican con el subsistema a través de la fachada, la cual reenvía las peticiones a los objetos apropiados. Por lo tanto, los clientes que usan esa interfaz no tienen por qué acceder directamente a las subclases del sistema, aunque pueden hacerlo.

Consecuencias

Las consecuencias más importantes que resultan de la aplicación de este patrón son la reducción del acoplamiento entre clientes y subsistemas (consiguiendo que los cambios de las clases del sistema sean transparentes a los clientes) y el aislamiento de cambios en la

Page 5: Resumen de Patrones

implementación. También oculta a los clientes la complejidad del subsistema, facilitando su uso sin impedir el acceso a las clases del subsistema en caso necesario. Además, facilita la división en capas y reduce dependencias de compilación.

Ventajas e inconvenientes

La principal ventaja del patrón fachada consiste en que para modificar las clases de los subsistemas, sólo hay que realizar cambios en la interfaz/fachada, y los clientes pueden permanecer ajenos a ello. Además, y como se mencionó anteriormente, los clientes no necesitan conocer las clases que hay tras dicha interfaz.

Como inconveniente, si se considera el caso de que varios clientes necesiten acceder a subconjuntos diferentes de la funcionalidad que provee el sistema, podrían acabar usando sólo una pequeña parte de la fachada, por lo que sería conveniente utilizar varias fachadas más específicas en lugar de una única global.

Patrones relacionados

Uno de los patrones relacionados más directamente es el singleton, dado que en determinadas ocasiones las fachadas pueden ser instancias únicas.

Otros patrones que guardan una cierta relación con el patrón fachada son los GRASP (General Responsibility Assignment Software Patterns), los cuales no son patrones de diseño, sino buenas prácticas que guían al desarrollador para encontrar los patrones de diseño, que son más concretos. Uno de los patrones GRASP es un controlador que actúa como punto de entrada en la capa lógica, lo que se puede comparar perfectamente con el uso del patrón fachada.

Usos conocidos (Problemas/Soluciones)

Problema: Un cliente necesita acceder a parte de la funcionalidad de un sistema más complejo.

Definir una interfaz que permita acceder solamente a esa funcionalidad.

Problema: Existen grupos de tareas muy frecuentes para las que se puede crear código más sencillo y legible.

Definir funcionalidad que agrupe estas tareas en funciones o métodos sencillos y claros.

Problema: Una biblioteca es difícilmente legible.

Crear un intermediario más legible.

Problema: Dependencia entre el código del cliente y la parte interna de una biblioteca.

Page 6: Resumen de Patrones

Crear un intermediario y realizar llamadas a la biblioteca sólo o, sobre todo, a través de él.

Problema: Necesidad de acceder a un conjunto de APIs que pueden además tener un diseño no muy bueno.

Crear una API intermedia, bien diseñada, que permita acceder a la funcionalidad de las demás.

Problema: Muchas clases cliente quieren usar varias clases servidoras, y deben saber cuál es exactamente la que le proporciona cada servicio. El sistema se volvería muy complejo, porque habría que relacionar todas las clases cliente con todas y cada una de las clases servidoras.

Crear una o varias clases Facade, que implementen todos los servicios, de modo que o todos los clientes utilicen esa única clase, o que cada grupo de clientes use la fachada que mejor se ajuste a sus necesidades.

Categoría:

Patrones de diseño

----------------------------------------------------------------------------------------------------------------------------------

State (patrón de diseño)El patrón de diseño State se utiliza cuando el comportamiento de un objeto cambia dependiendo del estado del mismo. Por ejemplo: una alarma puede tener diferentes estados, como desactivada, activada, en configuración. Definimos una interfaz Estado_Alarma, y luego definimos los diferentes estados.

Introducción

En determinadas ocasiones, cuando el contexto en el que se está desarrollando requiere que un objeto tenga diferentes comportamientos según el estado en que se encuentra, resulta complicado poder manejar el cambio de comportamientos y los estados de dicho objeto, todos dentro del mismo bloque de código. El patrón State propone una solución a esta complicación, creando básicamente, un objeto por cada estado posible del objeto que lo llama.

Propósito

Permite a un objeto alterar su comportamiento según el estado interno en que se encuentre.

Page 7: Resumen de Patrones

Motivación

El patrón State está motivado por aquellas clases en que, según su estado actual, varía su comportamiento ante los diferentes mensajes. Como ejemplo se toma una clase TCPConection 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.

Problema

Existe una extrema complejidad en el código cuando se intenta administrar comportamientos diferentes según una cantidad de estados diferentes. Asimismo el mantenimiento de este código se torna dificultoso, e incluso se puede llegar en algunos casos puntuales a la incongruencia de estados actuales por la forma de implementación de los diferentes estados en el código (por ejemplo con variables para cada estado).

Consideraciones

Se debe contemplar la complejidad comparada con otras soluciones.

Solución

Se implementa una clase para cada estado diferente del objeto y el desarrollo de cada método según un estado determinado. El objeto de la clase a la que le pertenecen dichos estados resuelve los distintos comportamientos según su estado, con instancias de dichas clases de estado. Así, siempre tiene presente en un objeto el estado actual y se comunica con este para resolver sus responsabilidades.

La idea principal en el patrón State es introducir una clase abstracta TCPState que representa los estados de la conexión de red y una interfaz para todas las clases que representan los estados propiamente dichos. Por ejemplo la clase TCPEstablished y la TCPClose implementan responsabilidades particulares para los estados establecido y cerrado respectivamente del objeto TCPConnection. La clase TCPConnection mantiene una instancia de alguna subclase de TCPState con el atributo state representando el estado actual de la conexión. En la implementación de los métodos de TCPConnection habrá llamadas a estos objetos representados por el atributo state para la ejecución de las responsabilidades, así según el estado en que se encuentre, enviará estas llamadas a un objeto u otro de las subclases de TCPState.

Page 8: Resumen de Patrones

Estructura UML

Participantes

1. Context(Contexto): Este integrante define la interfaz con el cliente. Mantiene una instancia de ConcreteState (Estado Concreto) que define su estado actual

2. State (Estado):Define una interfaz para el encapsulamiento de la responsabilidades asociadas con un estado particular de Context.

3. Subclase ConcreteState:Cada una de estas subclases implementa el comportamiento o responsabilidad de Context.

El Contexto (Context) 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.

Colaboraciones

El patrón State puede utilizar el patrón Singleton cuando requiera controlar que exista una sola instancia de cada estado. Lo puede utilizar cuando se comparten los objetos como Flyweight existiendo una sola instancia de cada estado y ésta es compartida con más de un objeto.

¿Cómo funciona?

La clase Context envía mensajes a los objetos ConcreteState dentro de su código para brindarle a estos la responsabilidad que debe cumplir el objeto Context. Así el objeto Context va cambiando las responsabilidades según el estado en que se encuentra, puesto que también cambia de objeto ConcreteState al hacer dicho cambio de estado.

¿Cuándo emplearlo?

Esta apuntado a cuando un determinado objeto tiene diferentes estados y también distintas responsabilidades según el estado en que se encuentre en determinado instante. También puede utilizarse para simplificar casos en los que se tiene un complicado y extenso código de decisión que depende del estado del objeto

Ventajas y desventajas

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

Page 9: Resumen de Patrones

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.

Conclusiones

El patrón no indica exactamente dónde definir las transiciones de un estado a otro. Existen dos formas de solucionar esto: Una es definiendo estas transiciones dentro de la clase contexto, la otra es definiendo estas transiciones en las subclases de State. Es más conveniente utilizar la primera solución cuando el criterio a aplicar es fijo, es decir, no se modificará. En cambio la segunda resulta conveniente cuando este criterio es dinámico, el inconveniente aquí se presenta en la dependencia de código entre las subclases.

También hay que evaluar en la implementación cuándo crear instancias de estado concreto distintas o utilizar la misma instancia compartida. Esto dependerá si el cambio de estado es menos frecuente o más frecuente respectivamente.

--------------------------------------------------------------------------------------------------------------------------------

Factory Method (patrón de diseño)En diseño de software, el patrón de diseño Factory Method consiste en utilizar una clase constructora (al estilo del Abstract Factory) abstracta con unos cuantos métodos definidos y otro(s) abstracto(s): el dedicado a la construcción de objetos de un subtipo de un tipo determinado. Es una simplificación del Abstract Factory, en la que la clase abstracta tiene métodos concretos que usan algunos de los abstractos; según usemos una u otra hija de esta clase abstracta, tendremos uno u otro comportamiento.

Page 10: Resumen de Patrones

Estructura

Las clases principales en este patrón son el creador y el producto. El creador necesita crear instancias de productos, pero el tipo concreto de producto no debe ser forzado en las subclases del creador, porque entonces las posibles subclases del creador deben poder especificar subclases del producto para utilizar.

La solución para esto es hacer un método abstracto (el método de la fábrica) que se define en el creador. Este método abstracto se define para que devuelva un producto. Las subclases del creador pueden sobrescribir este método para devolver subclases apropiadas del producto...

Categoría:

Patrones de diseño

-----------------------------------------------------------------------------------------------------------------------------------

Strategy (patrón de diseño)El patrón Estrategia (Strategy) es un patrón de diseño para el desarrollo de software. Se clasifica como patrón de comportamiento porque determina como se debe realizar el intercambio de mensajes entre diferentes objetos para resolver una tarea. El patrón estrategia permite mantener un conjunto de algoritmos de entre los cuales el objeto cliente puede elegir aquel que le conviene e intercambiarlo dinámicamente según sus necesidades.

Page 11: Resumen de Patrones

Motivación

Suponiendo un editor de textos con diferentes algoritmos para particionar un texto en líneas (justificado, alineado a la izquierda, etc.), se desea separar las clases clientes de los diferentes algoritmos de partición, por diversos motivos:

Incluir el código de los algoritmos en los clientes hace que éstos sean demasiado grandes y complicados de mantener y/o extender.

El cliente no va a necesitar todos los algoritmos en todos los casos, de modo que no queremos que dicho cliente los almacene si no los va a usar.

Si existiesen clientes distintos que usasen los mismos algoritmos, habría que duplicar el código, por tanto, esta situación no favorece la reutilización.

La solución que el patrón estrategia supone para este escenario pasa por encapsular los distintos algoritmos en una jerarquía y que el cliente trabaje contra un objeto intermediario contexto. El cliente puede elegir el algoritmo que prefiera de entre los disponibles, o el mismo contexto puede ser el que elija el más apropiado para cada situación.

Aplicabilidad

Cualquier programa que ofrezca un servicio o función determinada, que pueda ser realizada de varias maneras, es candidato a utilizar el patrón estrategia. Puede haber cualquier número de estrategias y cualquiera de ellas podrá ser intercambiada por otra en cualquier momento, incluso en tiempo de ejecución. Si muchas clases relacionadas se diferencian únicamente por su comportamiento, se crea una superclase que almacene el comportamiento común y que hará de interfaz hacia las clases concretas.

Si un algoritmo utiliza información que no deberían conocer los clientes, la utilización del patrón estrategia evita la exposición de dichas estructuras. Aplicando el patrón a una clase que defina múltiples comportamientos mediante instrucciones condicionales, se evita emplear estas instrucciones, moviendo el código a clases independientes donde se almacenará cada estrategia.

Efectivamente lo que se comenta anteriormente, este patron de diseño nos sirve para intercambian un sin número de estrategias posibles.

Estructura

Participantes

Contexto (Context) : Es el elemento que usa los algoritmos, por tanto, delega en la jerarquía de estrategias. Configura una estrategia concreta mediante una referencia a la estrategia necesaria. Puede definir una interfaz que permita a la estrategia el acceso a sus datos en caso de que fuese necesario el intercambio de información entre el contexto y la estrategia. En caso de no definir dicha interfaz, el contexto podría pasarse a sí mismo a la estrategia como parámetro.

Page 12: Resumen de Patrones

Estrategia (Strategy): Declara una interfaz común para todos los algoritmos soportados. Esta interfaz será usada por el contexto para invocar a la estrategia concreta.

EstrategiaConcreta (ConcreteStrategy): Implementa el algoritmo utilizando la interfaz definida por la estrategia.

Colaboraciones

Es necesario el intercambio de información entre estrategia y contexto. Este intercambio puede realizarse de dos maneras:

Mediante parámetros en los métodos de la estrategia. Mandándose, el contexto, a sí mismo a la estrategia.

Los clientes del contexto lo configuran con una estrategia concreta. A partir de ahí, solo se interactúa con el contexto.

Consecuencias

La herencia puede ayudar a factorizar las partes comunes de las familias de algoritmos (sustituyendo el uso de bloques de instrucciones condicionales). En este contexto es común la aparición conjunta de otros patrones como el patrón plantilla.

El uso del patrón proporciona una alternativa a la extensión de contextos, ya que puede realizarse un cambio dinámico de estrategia.

Los clientes deben conocer las diferentes estrategias y debe comprender las posibilidades que ofrecen.

Como contrapartida, aumenta el número de objetos creados, por lo que se produce una penalización en la comunicación entre estrategia y contexto (hay una indirección adicional).

Implementación

Entre las posibilidades disponibles a la hora de definir la interfaz entre estrategia y contexto, están:

Pasar como parámetro la información necesaria para la estrategia implica un bajo acoplamiento y la posibilidad de envío de datos innecesarios.

Pasar como parámetro el contexto y dejar que la estrategia solicite la información que necesita supone un alto acoplamiento entre ellos.

Mantener en la estrategia una referencia al contexto (similar al anterior).

También puede ocurrir que se creen y se utilicen los objetos estrategia en el contexto sólo si es necesario, en tal caso las estrategias serán opcionales.

Page 13: Resumen de Patrones

El diagrama de clases para este ejemplo sería como sigue, pudiéndose ver claramente la estructura del patrón:

Como podemos comprobar el funcionamiento de este patrón es muy simple y el añadir nuevas estrategias a nuestro programa es muy sencillo y apenas implica modificación de código alguna.

Categoría:

Patrones de diseño

----------------------------------------------------------------------------------------------------------------------------------

Null Object---------------------------------------------------------------------------------------------------------------------

Proxy (patrón de diseño)El patrón Proxy es un patrón estructural que tiene como propósito proporcionar un subrrogado o intermediario de un objeto para controlar su acceso.

Motivación

Para explicar la motivación del uso de este patrón veamos un escenario dónde su aplicación sería la solución más adecuada al problema planteado. Consideremos un editor que puede incluir objetos gráficos dentro de un documento. Se requiere que la apertura de un documento sea rápida, mientras que la creación de algunos objetos (imágenes de gran tamaño) es cara. En este caso no es necesario crear todos los objetos con imágenes nada más abrir el documento porque no todos los objetos son visibles. Interesa por tanto retrasar el coste de crear e inicializar un objeto hasta que es realmente necesario (por ejemplo, no abrir las imágenes de un documento hasta que no son visibles). La solución que se plantea para ello es la de cargar las imágenes bajo demanda. Pero, ¿cómo cargar las imágenes bajo demanda sin complicar el resto del editor? La respuesta es utilizar un objeto proxy. Dicho

Page 14: Resumen de Patrones

objeto se comporta como una imagen normal y es el responsable de cargar la imagen bajo demanda.

Aplicabilidad

El patrón proxy se usa cuando se necesita una referencia a un objeto más flexible o sofisticada que un puntero. Dependiendo de la función que se desea realizar con dicha referencia podemos distinguir diferentes tipos de proxies:

proxy remoto: representante local de un objeto remoto. proxy virtual: crea objetos costosos bajo demanda (como la clase ImagenProxy en el

ejemplo de motivación). proxy de protección: controla el acceso al objeto original (ejemplo de proxy de protección:

[1]) proxy de referencia inteligente: sustituto de un puntero que lleva a cabo operaciones

adicionales cuando se accede a un objeto (ej. contar número de referencias al objeto real, cargar un objeto persistente bajo demanda en memoria, control de concurrencia de acceso tal como bloquear el objeto para impedir acceso concurrente, …).

Participantes

La clase Proxy : mantiene una referencia al objeto real (en el siguiente ejemplo se le denomina _sujetoReal) y proporciona una interfaz idéntica al sujeto (la clase Sujeto). Además controla el acceso a dicho objeto real y puede ser el responsable de su creación y borrado. También tiene otras responsabilidades que dependen del tipo de proxy:

proxy remoto: responsable de codificar una petición y sus argumentos, y de enviarla al objeto remoto.

proxy virtual: puede hacer caché de información del objeto real para diferir en lo posible el acceso a este.

proxy de protección: comprueba que el cliente tiene los permisos necesarios para realizar la petición.

La clase Sujeto: define una interfaz común para el proxy (Proxy) y el objeto real (de la clase SujetoReal), de tal modo que se puedan usar de manera indistinta.

La clase SujetoReal: clase del objeto real que el proxy representa.

Colaboraciones.

Dependiendo de la clase de proxy, el objeto proxy redirige las peticiones al objeto real que representa.

Ejemplos de funcionamiento:

Diagrama de clases para un ejemplo del patrón proxy.[2]

Page 15: Resumen de Patrones

Diagrama de secuencia para un ejemplo en el que no se utiliza el patrón proxy. [3] Diagrama de secuencia para un ejemplo en el que se utiliza el patrón proxy.[4]

Consecuencias.

El uso de un proxy introduce un nivel de indirección adicional con diferentes usos:

Un proxy remoto oculta el hecho de que un objeto reside en otro espacio de direcciones. Un proxy virtual puede realizar optimizaciones, como la creación de objetos bajo

demanda. El proxy de protección y las referencias inteligentes permiten realizar diversas tareas de

mantenimiento adicionales al acceder a un objeto.

Además, su uso también permite realizar una optimización COW (copy-on-write) , puesto que copiar un objeto grande puede ser costoso, y si la copia no se modifica, no es necesario incurrir en dicho gasto. Además el sujeto mantiene un número de referencias, y sólo cuando se realiza una operación que modifica el objeto, éste se copia. Es útil por tanto para retrasar la replicación de un objeto hasta que cambia.

Patrones relacionados.

El patrón Adaptador proporciona una interfaz diferente al objeto que adapta, mientras que el proxy tiene la misma interfaz, pero ambos redirigen la petición del cliente al verdadero sujeto que la ejecuta con la posibilidad de incorporar lógica adicional : comprobación de acceso, creación del sujeto real…

El Proxy se puede diseñar de manera similar al patrón decorador, pero el propósito es diferente: el decorador añade responsabilidades a un objeto, el proxy sólo controla su acceso. Así, si el proxy no tiene una fuerte dependencia con el sujeto real (por ejemplo, no es de creación), y no tiene que instanciarlo, puede adoptar el mismo diseño que el decorador, y ser un proxy de cualquier sujeto (referencia a la interfaz que el cliente conoce).

Ejemplos comunes de la aplicación del patrón proxy.

A continuación se presentan algunos de los ejemplos más comunes en los que se utiliza el patrón proxy :

Añadir acceso de seguridad a un objeto existente. El proxy determinará si el cliente puede acceder al objeto de interés (proxy de protección).

Proporcionando interfaz de recursos remotos como el servicio web o recursos REST. Coordinación de las operaciones costosas en recursos remotos pidiendo los recursos a

distancia para iniciar la operación tan pronto como sea posible antes de acceder a los recursos.

Agregar una operación segura para los subprocesos a una clase existente sin cambiar el código de la clase existente.

Page 16: Resumen de Patrones

Categoría:

Patrones de diseño

------------------------------------------------------------------------------------------------------------------------

Observer (patrón de diseño)

El patrón Observador (en inglés: Observer) también conocido como "spider" define una dependencia del tipo uno-a-muchos entre objetos, de manera que cuando uno de los objetos cambia su estado, el observador se encarga de notificar este cambio a todos los otros dependientes.

El objetivo de este patrón es desacoplar la clase de los objetos clientes del objeto, aumentando la modularidad del lenguaje, así como evitar bucles de actualización (espera activa o polling).

Este patrón también se conoce como el patrón de publicación-inscripción o modelo-patrón. Estos nombres sugieren las ideas básicas del patrón, que son bien sencillas: el objeto de datos, llamémoslo "Sujeto" a partir de ahora, contiene atributos mediante los cuales cualquier objeto observador o vista se puede suscribir a él pasándole una referencia a sí mismo. El Sujeto mantiene así una lista de las referencias a sus observadores.

Los observadores a su vez están obligados a implementar unos métodos determinados mediante los cuales el Sujeto es capaz de notificar a sus observadores "suscritos" los cambios que sufre para que todos ellos tengan la oportunidad de refrescar el contenido representado. De manera que cuando se produce un cambio en el Sujeto, ejecutado, por ejemplo, por alguno de los observadores, el objeto de datos puede recorrer la lista de observadores avisando a cada uno.

Este patrón suele observarse en los frameworks de interfaces gráficas orientados a objetos, en los que la forma de capturar los eventos es suscribir 'listeners' a los objetos que pueden disparar eventos.

Page 17: Resumen de Patrones

En Java se puede heredar la funcionalidad del patrón Observer de la clase Observable y los observadores pueden implementar la interfaz Observer y por lo tanto redefinir el método update().

Categoría:

Patrones de diseño

-----------------------------------------------------------------------------------------------------------------------

Modelo Vista Controlador ESTA MAL

Un diagrama sencillo que muestra la relación entre el modelo, la vista y el controlador. Nota: las líneas sólidas indican una asociación directa, y las punteadas una indirecta (por ejemplo, patrón Observer).

Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que separa los datos de una aplicación, la interfaz de usuario, y la lógica de control en tres componentes distintos. El patrón de llamada y retorno MVC (según CMU), se ve frecuentemente en aplicaciones web, donde la vista es la página HTML y el código que provee de datos dinámicos a la página. El modelo es el Sistema de Gestión de Base de Datos y la Lógica de negocio, y el controlador es el responsable de recibir los eventos de entrada desde la vista.

Historia

El estilo fue descrito por primera vez en 1979[1] por Trygve Reenskaug, entonces trabajando en Smalltalk en laboratorios de investigación de Xerox. La implementación original está descrita en Programación de Aplicaciones en Smalltalk-80(TM): Como utilizar Modelo Vista Controlador.[2]

Page 18: Resumen de Patrones

Descripción del patrón

Modelo: Esta es la representación específica de la información con la cual el sistema opera. En resumen, el modelo se limita a lo relativo de la vista y su controlador facilitando las presentaciones visuales complejas. El sistema también puede operar con más datos no relativos a la presentación, haciendo uso integrado de otras lógicas de negocio y de datos afines con el sistema modelado.

Vista: Este presenta el modelo en un formato adecuado para interactuar, usualmente la interfaz de usuario.

Controlador: Este responde a eventos, usualmente acciones del usuario, e invoca peticiones al modelo y, probablemente, a la vista.

Muchos de los sistemas informáticos utilizan un Sistema de Gestión de Base de Datos para gestionar los datos: en líneas generales del MVC corresponde al modelo. La unión entre capa de presentación y capa de negocio conocido en el paradigma de la Programación por capas representaría la integración entre Vista y su correspondiente Controlador de eventos y acceso a datos, MVC no pretende discriminar entre capa de negocio y capa de presentación pero si pretende separar la capa visual gráfica de su correspondiente programación y acceso a datos, algo que mejora el desarrollo y mantenimiento de la Vista y el Controlador en paralelo, ya que ambos cumplen ciclos de vida muy distintos entre sí.

Aunque se pueden encontrar diferentes implementaciones de MVC, el flujo que sigue el control generalmente es el siguiente:

1. El usuario interactúa con la interfaz de usuario de alguna forma (por ejemplo, el usuario pulsa un botón, enlace, etc.)

2. El controlador recibe (por parte de los objetos de la interfaz-vista) la notificación de la acción solicitada por el usuario. El controlador gestiona el evento que llega, frecuentemente a través de un gestor de eventos (handler) o callback.

3. El controlador accede al modelo, actualizándolo, posiblemente modificándolo de forma adecuada a la acción solicitada por el usuario (por ejemplo, el controlador actualiza el carro de la compra del usuario). Los controladores complejos están a menudo estructurados usando un patrón de comando que encapsula las acciones y simplifica su extensión.

4. El controlador delega a los objetos de la vista la tarea de desplegar la interfaz de usuario. La vista obtiene sus datos del modelo para generar la interfaz apropiada para el usuario donde se reflejan los cambios en el modelo (por ejemplo, produce un listado del contenido del carro de la compra). El modelo no debe tener conocimiento directo sobre la vista. Sin embargo, se podría utilizar el patrón Observador para proveer cierta indirección entre el modelo y la vista, permitiendo al modelo notificar a los interesados de cualquier cambio. Un objeto vista puede registrarse con el modelo y esperar a los cambios, pero aun así el modelo en sí mismo sigue sin saber nada de la vista. El controlador no pasa objetos de dominio (el modelo) a la vista aunque puede dar la orden a la vista para que se actualice. Nota: En algunas implementaciones la vista no tiene acceso directo al modelo, dejando que el controlador envíe los datos del modelo a la vista.

5. La interfaz de usuario espera nuevas interacciones del usuario, comenzando el ciclo nuevamente.

Page 19: Resumen de Patrones

Categorías:

Patrones de diseño Arquitectura de software

------------------------------------------------------------------------------------------------------------------------

Composite (patrón de diseño)El patrón Composite sirve para construir objetos complejos a partir de otros más simples y similares entre sí, gracias a la composición recursiva y a una estructura en forma de árbol.

Esto simplifica el tratamiento de los objetos creados, ya que al poseer todos ellos una interfaz común, se tratan todos de la misma manera.

Problema que soluciona

Imaginemos que necesitamos crear una serie de clases para guardar información acerca de una serie de figuras que serán círculos, cuadrados y triángulos. Además necesitamos poder tratar también grupos de imágenes porque nuestro programa permite seleccionar varias de estas figuras a la vez para moverlas por la pantalla.

En principio tenemos las clases Círculo, Cuadrado y Triángulo, que heredarán de una clase padre que podríamos llamar Figura e implementarán todas la operación pintar(). En cuanto a los grupos de Figuras podríamos caer en la tentación de crear una clase particular separada de las anteriores llamada GrupoDeImágenes, también con un método pintar().

Problema.

Esta idea de separar en clases privadas componentes (figuras) y contenedores (grupos) tiene el problema de que, para cada uno de los dos atributos, el método pintar() tendrá una implementación diferente, aumentando la complejidad del sistema.

Implementación

El patrón Composite da una solución elegante a este problema, de la que además resulta en una implementación más sencilla.

A la clase Figura la llamaríamos Gráfico y de ella extenderían tanto Círculo, Cuadrado y Triángulo, como GrupoDeImágenes. Además, ésta última tendría una relación todo-parte de multiplicidad * con Gráfico: un GrupoDeImágenes contendría varios Gráficos, ya fuesen éstos Cuadrados, Triángulos, u otras clases GrupoDeImágenes.

Así, es posible definir a un grupo de imágenes recursivamente. Por ejemplo, un objeto cuya clase es GrupoDeImágenes podría contener un Cuadrado, un Triángulo y otro

Page 20: Resumen de Patrones

GrupoDeImágenes, este grupo de imágenes podría contener un Círculo y un Cuadrado. Posteriormente, a este último grupo se le podría añadir otro GrupoDeImágenes, generando una estructura de composición recursiva en árbol, por medio de muy poca codificación y un diagrama sencillo y claro.

Categoría:

Patrones de diseño

------------------------------------------------------------------------------------------------------------------------

Adapter (patrón de diseño)

El patrón Adapter (Adaptador) se utiliza para transformar una interfaz en otra, de tal modo que una clase que no pudiera utilizar la primera, haga uso de ella a través de la segunda.

Propósito

Convierte la interfaz de una clase en otra interfaz que el cliente espera. Adapter permite a las clases trabajar juntas, lo que de otra manera no podría hacerlo debido a sus interfaces incompatibles.

También conocido como

Wrapper (Envoltorio)

Aplicabilidad

usar el patrón Adapter cuando:

Se desea usar una clase existente, y su interfaz no se iguala con la necesitada. Cuando se desea crear una clase reusable que coopera con clases no relacionadas, es

decir, las clases no tienen necesariamente interfaces compatibles.

Page 21: Resumen de Patrones

Estructura

Una clase adaptadora usa múltiples herencias para adoptar una interfaz a otra.

Un objeto adaptador cuenta con la composición de objetos.

Participantes

Target define la interfaz específica del dominio que Client usa. Client colabora con la conformación de objetos para la interfaz Target. Adaptee define una interfaz existente que necesita adaptarse

Page 22: Resumen de Patrones

Adapter adapta la interfaz de Adaptee a la interfaz Target

Colaboraciones

Client llama a las operaciones sobre una instancia Adapter. De hecho, el adaptador llama a las operaciones de Adaptee que llevan a cabo el pedido.

Consecuencias

los adaptadores de clase y objetos tienen diferentes trade-off

Un adaptador de clase:o Adapta Adaptee a Target encargando a una clase Adaptee concreta. Como

consecuencia, una clase adaptadora no funcionará cuando se desea adaptar una clase y todas sus subclases.

o Permite a los Adapter sobrescribir algo de comportamiento de Adaptee, ya que Adapter es una subclase de Adaptee.

Un adaptador de objeto:o Permite que un único Adapter trabaje con muchos Adaptees, es decir, el Adapter

por sí mismo y las subclases (si es que la tiene). El Adapter también puede agregar funcionalidad a todos los Adaptees de una sola vez.

o Hace difícil sobrescribir el comportamiento de Adaptee. Esto requerirá derivar Adaptee y hacer que Adapter se refiera a la subclase en lugar que al Adaptee por sí mismo.

Aquí hay otras cuestiones a considerar cuando se utiliza el patrón Adapter:

1.¿Cuanta adaptación hace el Adapter? Adapter varía en la cantidad de trabajo que hace para adaptar Adaptee a la interfaz Target. Hay un espectro de trabajo posible, desde una simple conversión (por ejemplo, cambiando los nombres de las operaciones) hasta soportando un conjunto de operaciones enteramente diferentes. La cantidad de trabajo que Adapter hace depende de cuanto de similar tienen la interfaz Target con Adaptee.

2.Adaptadores Pluggables Una clase es más reusable cuando se minimiza la suposición de que otras clases deben utilizarla. Mediante la construcción en una clase de la adaptación de una interfaz, se elimina la suposición de que otras clases ven la misma interfaz. Dicho de otra manera, la adaptación de la interfaz nos permite incorporar a nuestra clase en sistemas existentes que pueden esperar diferentes interfaces de la misma.

Implementación

Crear una nueva clase que será el Adaptador, que extienda del componente existente e implemente la interfaz obligatoria. De este modo tenemos la funcionalidad que queríamos y cumplimos la condición de implementar la interfaz.

La diferencia entre los patrones Adapter y Facade, es que el primero reutiliza una interfaz ya existente, mientras que el segundo define una nueva con el objetivo de simplificarla.

Page 23: Resumen de Patrones

Categoría:

Patrones de diseño

------------------------------------------------------------------------------------------------------------------------

Decorator (patrón de diseño)De Wikipedia, la enciclopedia libre

Saltar a: navegación, búsqueda

El patrón Decorator responde a la necesidad de añadir dinámicamente funcionalidad a un Objeto. Esto nos permite no tener que crear sucesivas clases que hereden de la primera incorporando la nueva funcionalidad, sino otras que la implementan y se asocian a la primera.

Problema que soluciona

Supongamos que tenemos una clase existente Ventana y queremos añadirle funcionalidad para que muestre un borde alrededor. Podemos crear una subclase VentanaConBorde que herede de Ventana.

Hasta aquí todo bien, pero supongamos que surge la necesidad de crear una ventana que muestre un pequeño botón de ayuda con un signo de interrogación (?) en su parte superior. Entonces tenemos las siguientes opciones:

Page 24: Resumen de Patrones

Crear otra subclase de Ventana: VentanaConBotónDeAyuda.

Problema: No cubre la necesidad de tener ventanas con bordes y botón de ayuda a la vez.

Crear una subclase de VentanaConBorde: VentanaConBordeYBotonDeAyuda.

Problema: No tenemos una ventana con botón de ayuda y sin borde.

Crear clases para todas las combinaciones posibles de funcionalidades.

Problema: Con este ejemplo tendríamos cuatro clases: Ventana, VentanaConBorde, VentanaConBotonDeAyuda y VentanaConBordeYBotonDeAyuda; con tres funcionalidades tendríamos ocho clases y con cuatro, ¡dieciséis!

Aplicabilidad

Añadir objetos individuales de forma dinámica y transparente Responsabilidades de un objeto pueden ser retiradas Cuando la extensión mediante la herencia no es viable Hay una necesidad de extender la funcionalidad de una clase, pero no hay razones para

extenderlo a través de la herencia. Hay la necesidad de extender dinámicamente la funcionalidad de un objeto y quizás quitar

la funcionalidad extendida.

Implementación

El patrón Decorator soluciona este problema de una manera mucho más sencilla y extensible.

Se crea a partir de Ventana la subclase abstracta VentanaDecorator y, heredando de ella, BordeDecorator y BotonDeAyudaDecorator. VentanaDecorator encapsula el comportamiento de Ventana y utiliza composición recursiva para que sea posible añadir tantas "capas" de Decorators como se desee. Podemos crear tantos Decorators como queramos heredando de VentanaDecorator.

Categoría: Patrones de diseño

------------------------------------------------------------------------------------------------------------------------