8 de julio de 2013

PATRONES DE DISEÑO

INTRODUCCION

El objetivo del diseño de software es llegar a un producto de calidad. El diseño debe ser adecuado para la aplicación en particular, pero dicha solución también debe ser general para poder enfrentar distintos escenarios y evitar el rediseño. No es necesario partir desde cero.
Los patrones de diseño de software nacen en los 80’s con Kent Beck y Ward Cunningham, que discutían patrones para Smalltalk. La contribución más célebre es el libro “Patrones de Diseño”

¿QUE ES UN PATRON DE DISEÑO?

De acuerdo al arquitecto Christopher Alexander, “cada patrón de diseño describe un problema que ocurre una y otra vez en nuestro entorno, así como la solución a ese problema de tal modo que se pueda aplicar esta solución una y otra vez, sin repetir cada vez lo mismo”.

¿POR QUÉ UTILIZAR LOS PATRONES DE DISEÑO?

Su utilización y documentación permite a desarrolladores novatos beneficiarse de la experiencia de soluciones anteriores. Proporcionan un vocabulario común a los desarrolladores, mejorando la comunicación de soluciones entre ellos. Además al tener conocimiento sobre patrones, es posible obtener mejores diseños
·         Las soluciones con patrones resuelven problemas específicos hacen los diseños orientados a objetos más flexibles, elegantes y sobre todo reutilizables.

·         Facilitan la reutilización de diseños y arquitecturas de software que han tenido éxito.

·         Ayudan a comprender mejor un sistema cuando está documentado con los patrones que se utilizaron en su desarrollo.

·         Facilitan la reestructuración de un sistema. Y permite adaptarse más rápido y de mejor forma a las modificaciones que se dan en los sistemas durante un período de tiempo.

ELEMENTOS DE UN PATRON DE DISEÑO


En general un patrón tiene cuatro elementos esenciales:
   1)    El nombre del patrón: permite describir, en una o dos palabras, un problema de diseño con sus soluciones y consecuencias.
 2)    El problema: describe cuando aplicar el patrón. Explica el problema y su contexto.
    3)    La solución: describe los elementos que constituyen el diseño, sus relaciones, responsabilidades y colaboraciones. La solución no describe un diseño o una implementación en concreto, sino que un patrón es más bien como una plantilla que puede aplicarse en muchas situaciones diferentes.
4)    Las consecuencias: son los resultados así como las ventajas e inconvenientes de aplicar el patrón.

¿CÓMO SE CLASIFICAN LOS PATRONES DE DISEÑO?

Los patrones de diseño se clasifican de acuerdo a:
Su propósito:
·         Patrones de creación. Se refieren a la creación de instancias.
·         Patrones estructurales. Se refieren a las relaciones entre clases y/u objetos.
·         Patrones de comportamiento. Caracterizan la forma en que las clases u objetos interactúan y distribuyen sus responsabilidades (servicios).
Su ámbito:
·         Patrones de clases. Tratan con relaciones de herencia (estática) entre clases.
·         Patrones de objetos. Se refieren a relaciones de composición entre objetos, que pueden cambiar en tiempo de ejecución y son más dinámicas.



Creacionales
  • Creacional de la Clase
    Los patrones creacionales de Clases usan la herencia como un mecanismo para lograr la instanciación de la Clase. Por ejemplo el método Factoría.
  • Creacional del objeto
    Los patrones creacionales de objetos son más escalables y dinámicos comparados de los patrones creacionales de Clases. Por ejemplo la Factoría abstracta y el patrón Singleton.
Estructurales
  • Estructural de la Clase
    Los patrones estructurales de Clases usan la herencia para proporcionar interfaces más útiles combinando la funcionalidad de múltiples Clases. Por ejemplo el patrón Adaptador (Clase).
  • Estructural de Objetos
    Los patrones estructurales de objetos crean objetos complejos agregando objetos individuales para construir grandes estructuras. La composición de l patrón estructural del objeto puede ser cambiado en tiempo de ejecución, el cual nos da flexibilidad adicional sobre los patrones estructurales de Clases. Por ejemplo el Adaptador (Objeto), Facade, Bridge, Composite.
Comportamiento
  • Comportamiento de Clase
    Los patrones de comportamiento de Clases usan la herencia para distribuir el comportamiento entre Clases. Por ejemplo Interpreter.
  • Comportamiento de Objeto
    Los patrones de comportamiento de objetos nos permite analizar los patrones de comunicación entre objetos interconectados, como objetos incluidos en un objeto complejo. Ejemplo Iterator, Observer, Visitor.

A continuación se presentan los 13 patrones más utilizados para el desarrollo del software

Data Acces Object (DAO)

Este patrón es muy utilizado en el contexto JDBC. Abstrae y encapsula todos los accesos al servidor aislando los objetos de negocio de una implementación particular de la persistencia.

El objeto DAO maneja la conexión con el servidor para obtener y modificar datos implementando los mecanismos de acceso requeridos para trabajar con la base de datos.

Para acceder a datos resistentes en bases de datos relacionales, el API JDBC proporciona acceso y manipulación de datos utilizando sentencias SQL. Sin embargo, incluso en estos entornos de bases de datos relacionales, la actual sintaxis y formato de las sentencias SQL pueden variar dependiendo de la base de datos en particular.

Pero las diferencias son mayores cuando se utilizan distintos mecanismos para el almacenamiento de datos. Para evitar dependencias directas de nuestro código con los mecanismos de almacenamiento de datos es especialmente útil la aplicación de este patrón de diseño.

El patrón de diseño DAO implementa el mecanismo de acceso requerido para trabajar con el servidor. Este podría ser considerado como un almacenamiento persistente como un RDBMS, un repositorio como una base de datos, o un servicio de negocio accesible a través de CORBA Internet Inter-ORB Protocol (IIOP) o sockets de bajo nivel. Los componentes de negocio que se basan en DAO utilizan la interfaz más simple expuesta por DAO para sus clientes. DAO oculta completamente los detalles del origen de datos de la aplicación hacia sus clientes. Debido a que la interfaz expuesta por el DAO a los clientes no cambia cuando los datos subyacentes cambian su implementación de código, este modelo permite al DAO adaptarse a los sistemas de almacenamiento sin que ello afecte a sus clientes o componentes de negocio. Esencialmente, DAO actúa como un adaptador entre el componente y la fuente de datos

·         Estructura (diagrama de clases)


·         Diagrama de secuencia

·         Participantes

-       BusinessObject
El BusinessObject representa al cliente los datos. Es el objeto que requiere el acceso al servidor para obtener y almacenar datos. BusinessObject puede ser implementado como un bean de sesión, beans de entidad, o algún otro objeto Java, además de un servlet o un helper bean que accede a la fuente de datos.
-       DataAccessObject
El DataAccessObject es el objeto principal de este patrón. El DataAccessObject abstrae la implementación del acceso a los datos subyacentes para el BusinessObject para permitir el acceso transparente al servidor. El BusinessObject también delega la carga de datos y operaciones de almacenamiento al DataAccessObject.
-       DataSource
Esto representa una implementación del servidor. Una fuente de datos podría ser una base de datos como un RDBMS, SGBDOO, repositorio XML,sistema de archivos planos, y así sucesivamente. Una fuente de datos también puede ser otro sistema, servicios, o algún tipo de repositorio (LDAP).
-       TransferObject

Esto representa un objeto de transferencia que se utiliza como soporte de datos. El DataAccessObject puede utilizar un objeto de transferencia para devolver los datos al cliente. El DataAccessObject también pueden recibir los datos del cliente en un objeto de transferencia para actualizar los datos del origen de datos.

Composite View

Gestiona los diferentes elementos de la vista por medio de una plantilla que hace la representación de las vistas más manejable. Con este patrón se tiende a utilizar vistas compuestas que están formadas por múltiples sub-vistas.
El abuso de estas subdivisiones puede tener un efecto negativo en el rendimiento por lo que es conveniente alcanzar un compromiso entre modularidad y mantenimiento frente a rendimiento.

·         Propósito
Crear Vistas Compuestas de varias sub-vistas de forma modular, flexible y extensible para construir vistas de páginas JSP para aplicaciones J2EE.

·         Descripción
Cuando un usuario navega a través de aplicaciones gráficas los datos y el contenido entre las  diferentes páginas varía, pero muchos elementos, como una cabecera común o una barra lateral permanecen intactos en todas las vistas. La estructura y disposición de cada página puede ser la  misma y algunos elementos o secciones de la página pueden aparecer en varias páginas  diferentes. Cuando estos elementos y grupos se codifican directamente en la aplicación se  vuelve muy difícil la tarea de modificar las vistas y se puede incurrir en inconsistencias.
Las páginas Web sofisticadas presentan contenido de varias fuentes de datos, utilizando  una Vista Compuesta (Composite View) formada por otras sub-vistas. Cualquier cambio realizado en una sub-vista es reflejado automáticamente en cada Vista Compuesta que la utilice.
La Vista Compuesta también maneja la disposición de sus sub-vistas y proporciona una  plantilla, dando una apariencia consistente y facilidades a la hora de modificarla y mantenerla a  lo largo de toda la aplicación.

·         Aplicación
Se usará el patrón Composite View cuando:
-       Varias vistas compuestas utilizan sub-vistas similares.
-       Las porciones atómicas del contenido de una vista cambian con frecuencia.

·         Estructura

·         Participantes

-       Vistas Compuestas
Una Vista Compuesta es una vista a la que se le han agregado varias sub-vistas.
-       View Manager (Controlador de Vistas)
El Controlador de Vista maneja la inclusión de fragmentos de una plantilla en la Vista Compuesta. El Controlador de Vista podría ser parte de un motor de ejecución estándar de páginas JSP, en la forma de la etiqueta <jsp:include> de JSP (véase figura), o podría encapsularse dentro de un helper JavaBean o una etiqueta personalizada, para proporcionar una funcionalidad más robusta.
-       Vistas Incluidas
Una Vista Incluida es una sub-vista, una pieza atómica de una vista mayor. Esta vista incluida  también podría ser una vista compuesta, incluyendo varias sub-vistas.
·         Diagrama de secuencia

·         Consecuencias

-       Cada componente de la plantilla puede incluirse dinámicamente dentro del todo y la  distribución de la página puede manejarse de forma independiente del contenido.

-       Esta solución es útil para la creación de vistas basadas en la inclusión y sustitución de fragmentos de plantilla modulares, tanto estáticos como dinámicos. Los diseñadores pueden hacer un prototipo de la distribución de la web, poniendo contenido estático en cada región de la plantilla. Según va progresando el desarrollo, este contenido se puede ir sustituyendo por el contenido dinámico.

-       Promueve la reutilización de porciones atómicas de la vista, animando a realizar diseños modulares.

-       Es apropiado utilizar este patrón para generar páginas que muestren componentes que  podrían combinarse de diferentes maneras. Esto ocurre, por ejemplo, con portales que  incluyan numerosas sub-vistas independientes, como noticias, información del tiempo, etc. en una sola página.

-       La distribución de la página se maneja y modifica de forma independiente al contenido de las sub-vistas.

-       Provoca una sobrecarga en tiempo de ejecución, un precio que hay que pagar por el incremento de flexibilidad que proporciona.


·         Patrones relacionados

El patrón de vista compuesta se podría utilizar como la vista del patrón View Helper. Así la  vista compuesta delega sus responsabilidades de procesamiento en sus clases de ayuda,  implementadas como JavaBeans o etiquetas personalizadas. Las clases de ayuda o helpers también almacenan el modelo de datos intermedio de la vista y sirven como adaptadores de  datos de negocio.

Composite Entity

En una aplicación de la plataforma J2EE, los clientes -- como aplicaciones, páginas JSP, servlets, componentes JavaBeans, acceden a los beans de entidad mediante sus interfaces remotas. Así, toda llamada de un cliente potencialmente se enruta a través de los stubs (trozos) y skeletons(esqueletos), incluso si el cliente y el bean enterprise están en la misma Máquina Virtual Java, en el mismo sistema operativo o en la misma máquina física.

Cuando los beans enterprise son objetos específicos, los clientes tienden a invocar los métodos del bean de forma más individual, resultando en una gran sobrecarga en la red.

Hay varias áreas que se ven impactadas por la aproximación del diseño del bean de entidad específico:
·         Relaciones de Entidades - Mapear directamente un objeto de modelo a un modelo EJB no tiene en cuenta el impacto de las relaciones entre objetos. Las relaciones inter-objetos se transforman directamente en relaciones inter-beans. Como resultado, un bean de entidad podría contener o almacenar una referencia remota a otro bean de entidad. Sin embargo, mantener referencias remotas a objetos distribuidos implica técnicas y semánticas diferentes a la de mantener referencias a objetos locales. Junto con el incremento de complejidad del código, se reduce la flexibilidad porque el bean de entidad debe cambiar si cambia alguna de sus relaciones. 
Además, no hay garantías de la validez de las referencias de un bean de entidad a otro bean de entidad en el tiempo. Dichas referencias se establecen dinámicamente utilizando el objeto home de la entidad y la clave primaria para ese ejemplar de bean. Esto implica una alta sobrecarga de mantenimiento para el chequeo de validez de la referencia por cada referencia de bean-de-entidad-a-bean-de-entidad.
·         Manejabilidad - Implementar objetos específicos como beans de entidad resulta en un mayor número de beans de entidad en el sistema, el desarrollador debe proporcionar clases para el interface home, el interface remote, la implementación del bean y la clave primaria. 
Además, el contenedor podría generar clases para soportar la implementación del bean de entidad. Cuando se crea el bean, estas clases se convierten en objetos reales en el contenedor. En breve, el contenedor crea varios objetos para soportar cada ejemplar de bean de entidad. Un mayor número de beans de entidad significa más clases y código que mantener por el equipo de desarrollo. También resulta en un mayor número de objetos en el contenedor. Esto puede impactar negativamente en el rendimiento de la aplicación.
·         Rendimiento de Red -- los beans de entidad específicos, potencialmente tienen más relaciones inter-beans. Los beans de entidad son objetos distribuidos. Cuando un bean de entidad invoca un método de otro bean de entidad, el contenedor trata esa llamada como una llamada remota, incluso si ambos beans están en el mismo contenedor. Si el número de relaciones bean-de-entidad-a-bean-de-entidad se incrementa, se reduce la escalabilidad del sistema debido a la fuerte sobrecarga de la red.
·         Dependencia del Esquema de Base de Datos - Cuando los beans de entidad son específicos cada ejemplar normalmente representa una sóla fila de la base de datos. Esto no es una aplicación apropiada del diseño de beans de entidad, ya que los beans de entidad son más apropiados para componentes genéricos. La implementación de beans de entidad específicos normalmente es una representación directa del esquema de la base de datos subyacente en el diseño del bean de entidad. Cuando los clientes utilizan estos beans de entidad específicos, están operando esencialmente a nivel de fila en la base de datos, ya que cada bean de entidad efectivamente es una única fila. Como el bean de entidad modela directamente una sola fila de la base de datos, los clientes dependen del esquema de la base de datos. Cuando el esquema cambia, también deben cambiar las definiciones del bean de entidad. Además, como los clientes están operando con la misma especificidad, deben observar y reaccionar ante estos cambios. Esta dependencia del esquema causa una pérdida de flexibilidad e incrementa la sobrecarga de mentenimiento requerida cuando cambia el esquema.
·         Especificidad del Objeto (Genérico frente a Específico) -- La especificidad del objeto impacta en la transferencia de datos entre el bean enterprise y el cliente. En muchas aplicaciones, los clientes necesitan un trozo de datos mayor que una o dos filas de la tabla. En dichos casos, implementar cada unos de estos objetos específicos como un bean de entidad significa que el cliente tendría que manejar las relaciones entre todos esos objetos específicos. Dependiendo de los requerimientos de datos, el cliente podría tener que realizar muchas búsquedas de varios beans de entidad para obtener la información necesaria.
Los clientes no necesitan conocer la implementación del esquema de la base de datos para utilizar y soportar los beans de entidad. Con beans de entidad específicos, el mapeo se hace normalmente para que cada ejemplar de bean de entidad corresponda con una sola fila de la base de datos. Este mapeo específico crea una dependencia entre el cliente y el esquema de la base de datos subyacente, ya que el cliente trata con beans específicos y éstos esencialmente son una representación directa del esquema subyacente. Esto resulta en un fuerte acoplamiento entre el esquema de la base de datos y los beans de entidad. Un cambio en el esquema causa el cambio correspondiente en el bean de entidad, y además requiere el cambio correspondiente en los clientes.

Una solución a los problemas que se presentan es utilizar Composite Entity para modelar, representar y manejar un conjunto de objetos persistentes relacionados en vez de representarlos como beans de entidad específicos individuales. Un bean Composite Entity representa un grupo de objetos.
Para entender esta solución, primero definamos que significan los objetos persistentes y discutiremos sus relaciones.
Un objeto persistente es un objeto que se almacena en algún tipo de almacenamiento. Normalmente múltiples clientes comparten los objetos persistentes. Los objetos persistentes se pueden clasificar en dos tipos: objetos genéricos y objetos dependientes.
Un objeto genérico es autosuficiente. Tiene su propio ciclo de vida y maneja sus relaciones con otros objetos. Todo objeto genérico podría referenciar o contener uno o más objetos. El objeto genérico normalmente maneja el ciclo debida de estos objetos. De ahí, que esos objetos sean conocidos como objetos dependientes. Un objeto dependiente puede ser un simple objeto auto-contenido o podría a su vez contener otros objetos dependientes.
Un bean Composite Entity puede representar un objeto genérico y todos sus objetos dependientes relacionados. Esta combinación de objetos persistentes relacionados dentro de un sólo bean de entidad reduce drásticamente el número de beans de entidad requeridos por la aplicación. Esto genera un bean de entidad altamente genérico que puede obtener mejor los beneficios de los beans de entidad que un bean de entidad específico.
Sin la aproximación Composite Entity, hay una tendencia a ver todos los objetos genéricos y dependientes como beans de entidad separados, suponiendo un gran número de beans de entidad.

·         Estructura (diagrama de clases)

·         Diagrama de flujo de datos
·         Participantes
-       CompositeEntity
CompositeEntity es un bean de entidad genérico. Podría ser un objeto genérico, o podría contener una referencia a un objeto genérico.
-       Coarse-Grained Object
Un objeto genérico es un objeto que tiene su propio ciclo de vida y que maneja sus propias relaciones con otros objetos. Un objeto genérico puede ser un objeto Java contenido en el CompositeEntity. O, el propio Composite Entity puede ser un objeto genérico que contiene objetos dependientes.
-       DependentObject1, DependentObject2, y DependentObject3

Un objeto dependiente es un objeto que depende de un objeto genérico el cual gobierna el ciclo de vida del objeto dependiente. Un objeto dependiente puede contener otros objetos dependientes; así podría existir un árbol de objetos dentro del Composite Entity.

Business Delegate

Este patrón es utilizado en sistemas multi-capa distribuidos cuando es necesaria la invocación de métodos remotos para enviar y recibir datos entre las distintas capas del sistema.
Evita que los componentes de la capa de presentación interactúen directamente con los servicios de negocio y sean vulnerables a los cambios en la capa de negocio. Si no se empleara este patrón sería necesario exponer la implementación de la interfaz del servicio de negocio a la capa de presentación obteniendo una fuerte dependencia entre ambas capas.
Este patrón reduce el acoplamiento entre los clientes y la capa de negocio, ocultando los detalles de la implementación de los servicios de negocios y búsquedas y accesos asociados en los sistemas distribuidos.
Otras de las ventajas del uso de este patrón es la posibilidad de dotarlo de la capacidad de almacenar resultados y referencias a servicios remotos que puede mejorar considerablemente el rendimiento.
Puede utilizarse como interfaz entre distintas capas, ya que no se restringe su uso a la separación de las capas de presentación y modelo.
Normalmente el business delegate oculta a otro patrón, el session façade, ocultando la tecnología utilizada en el modelo.
El business delegate actúa como una abstracción de negocio del lado del cliente; y por lo tanto oculta, la implementación de los servicios del negocio. Utilizando business delegate se reduce el acoplamiento entre los clientes de la capa de presentación y los servicios de negocio del sistema.

Si bien es cierto, que los cambios se harán con más probabilidad en el servicio de negocio que en el business delegate.

El principal beneficio de utilizar este patrón es ocultar los detalles del servicio. Por ejemplo, el cliente puede ser transparente para los servicios de búsqueda y nombrado. El business delegate también maneja las excepciones de los servicios de negocio, como excepciones java.rmi.remote, excepciones java messages service (jms), etc. el business delegate podría interceptar dichas excepciones a nivel de servicio y generar en su lugar excepciones a nivel de aplicación. Las excepciones de nivel de aplicacion son fáciles de manejar por los clientes, y pueden ser amigables para el usuario. El business delegate también podría realizar de forma transparente cualquier operación de reintento o de recuperación necesaria en el caso de un fallo en el servicio otro beneficio es que el delegado podría almacenar resultados y referencias a servicios de negocio remotos.
Un business delegate utiliza un componente llamado lookup service. Este componente es el responsable de ocultar los detalles de implementación de código de búsqueda del servicio de negocio. El lookup service podría estar escrito como parte del delegate, pero es recomendable implementarlo como un componente separado.




·         Estructura (diagrama de clases)

El cliente solicita al BusinessDelegate que le proporcione acceso al servicio de negocio subyacente. El BusinessDelegate utiliza un LookupService para localizar el componente BusinessService requerido.

·         Diagrama de secuencia