jueves, 19 de mayo de 2011

Aplicaciones con el patrón de diseño Model-View/ViewModel


Desarrollar una interfaz de usuario de una aplicación profesional de software no es fácil. Puede ser una mezcla turbia de datos, diseño de interacción, diseño visual, conectividad, multitareas, seguridad, internacionalización, validación, test unitario y un toque de voodoo. Considerando que la interfaz del usuario expone un sistema y debe satisfacer los requerimientos de estilo impredecibles del usuario, puede ser el área más volátil de muchas aplicaciones.
Existen patrones de diseño populares que pueden ayudar a domar esta bestia difícil de manejar, pero separar y direccionar una multitud de preocupaciones puede ser difícil. Cuanto más complicados son los patrones, es más seguro que serán utilizados shortcuts que disminuyen los esfuerzos previos para hacer las cosas en el modo correcto.
No siempre falla el patrón de diseño. A veces utilizamos patrones de diseño complicados, lo cuales requieren la escritura de mucho código porque la plataforma UI en uso no se presta a sí misma para los patrones más sencillos. Lo que se necesita es una plataforma que haga fácil construir UIs utilizando patrones de diseño simples, testeados en el tiempo, y aprobados por desarrolladores. Afortunadamente, WPF y Silverlight proveen exactamente esto.
Mientras el mundo del software continua a adoptar WPF y Silverlight en un gran porcentaje, la comunidad ha estado desarrollando su propio ecosistema de patrones y prácticas. Hoy voy a revisar algunos de esas mejores prácticas para diseñar e implementar aplicaciones clientes con WPF/Silverlight. Aprovechando algunas características core de WPF en conjunto con el patrón de diseño Model-View-ViewModel, haremos un ejemplo de programa que demuestra cuan simple puede ser crear una aplicación WPF en el modo correcto.
Al finalizar este artículo, será claro como las plantillas de datos, comandos, enlace de datos, el sistema de recursos, y el patrón MVVM todos encajan para crear una aplicación simple, testable y robusta. El programa de demostración que acompaña este articulo puede servir como plantilla para una aplicación WPF que utiliza MVVM como su arquitectura central. Los test unitarios en la solución demo muestran como es fácil testear la funcionalidad de una interface de usuario cuando la funcionalidad existe en un conjunto de clases ViewModel. Antes de profundizar en los detalles, veamos porque debemos utilizar el patrón MVVM en primer lugar.
Orden vs Caos
Es innecesario y contraproducente usar un patrón de diseño en un programa simple Hello World. Cualquier desarrollador competente puede entender unas pocas líneas de código de un vistazo. Sin embargo, en la medida que el número de características en un programa se incrementa, el número de líneas de código y partes movibles incrementan en consecuencia. Eventualmente, la complejidad de un sistema, y los problemas recurrentes que contienen, alientan a los desarrolladores a organizar su código en un modo que es fácil de comprender, discutir, extender y solucionar problemas. Nosotros disminuimos el caos cognitivo de un sistema complejo aplicando nombres bien conocidos a ciertas entidades en el código fuente. Determinamos el nombre a aplicar a cada pieza de código considerando su rol funcional en el sistema.
Los desarrolladores a menudo estructuran su código de acuerdo a un patrón de diseño, opuesto a dejar que el patrón emerja naturalmente. No hay nada mal con ambos enfoques, pero en este artículo, examino los beneficios de utilizar explícitamente MVVM como la arquitectura de la aplicación. Los nombres de ciertas clases incluyen términos bien conocidos del patrón MVVM, como por ejemplo finalizar el nombre de la clase con ViewModel si la clase es una abstracción de una vista. Este enfoque ayuda a evitar el caso cognitivo mencionado anteriormente. En su lugar, puede felizmente existir en un estado de caos controlado, el cual es un estado natural en la mayorías de los proyectos de desarrollo profesionales.
La evolución del Model-View-ViewModel
Desde que la gente inicio a crear interfaces de usuario, existieron patrones de diseño populares para ayudar a hacer el trabajo más fácilmente. Por ejemplo, el Model-View-Presenter (MVP) tuvo popularidad en varias plataformas de programación de UI. MVP es una variación del patrón Model-View-Controller, el cual estuvo presente por décadas. En el caso en que nunca haya utilizado el patrón MVP, esta es una explicación simple. Lo que vemos en la pantalla es la View, los datos que muestra la View es el modelo, y el Presenter engancha los dos juntos. La view se basa en el Presenter para popular con los datos del modelo, reaccionar a la entrada del usuario, dar validación de entrada, y otras tareas.
Tiempo atrás 2004, Martin Fowler público un artículo a cerca de un patrón llamado Presentation Model (PM), el cual es similar al MVP en que separa una view de su comportamiento y estado. La parte interesante del patrón es que una abstracción de la vista es creada, llamada Presentation Model (modelo de presentación). Una view, entonces, se transforma en una representación del Presentation Model (modelo de presentación). En la explicación de Fowler, muestra que el Presentation Model frecuentemente actualiza la View, de modo que las dos permanecen en sincronía una con la otra. Esta lógica de sincronización existe como código en las clases del Presentation Model.
En 2005, John Gossman, actualmente uno de los arquitectos Microsoft de WPF y Silverlight, dio a conocer el patrón Model-View-ViewModel en su blog. El cual es idéntico al patrón de Fowler (Presentation Model), en que ambos patrones tienen como característica común la abstracción de una View, la cual contiene el estado y comportamiento de la View. Fowler introdujo Presentation Model como un medio para la creación de la abstracción de una view independiente de la plataforma de UI, donde Gossman introdujo MVVM como un modo estandarizado de aprovechar características centrales de WPF para simplificar la creación de interfaces de usuario. En ese sentido, yo considero MVVM a ser una especialización del patrón más general del Presentation Model, hecho a medida para las plataformas WPF y Silverlight.
A diferencia del Presenter en MVP, un ViewModel no necesita una referencia a una view. La view se enlaza a  propiedades de un ViewModel, el cual, a su vez, expone datos contenidos en objetos del modelo y  otro estado especifico a la view.  Los enlaces entre view y ViewModel son simples de construir porque un objeto ViewModel es establecido como DataContext de la View. Si los valores de las propiedades en el ViewModel cambian, estos nuevos valores automáticamente se propagan a la vista a través del enlace de datos. Cuando un usuario hace clic en un botón en la view, un comando en el ViewModel se ejecuta para realizar la acción requerida. El ViewModel, nunca la Vista, realiza modificaciones hechas a los datos del modelo.
Las clases View no tienen idea que las clases del modelo existen, mientras el ViewModel y el modelo están inconscientes de la view. Este es un diseño de acoplamiento flexible, que paga en muchos modos, como veremos.
Porque los desarrolladores aman MVVM
Una vez que el desarrollador esta cómodo con WPF/Silverlight y MVVM, puede ser difícil diferenciarlos. MVVM es lengua franca de los desarrolladores WPF Silverlight porque es bien adecuado para la plataforma, y WPF fue diseñado para hacer las cosas fáciles al construir aplicaciones usando el patrón MVVM. De hecho, Microsoft estaba utilizando MVVM internamente para desarrollar aplicaciones WPF como Expression Blend, mientras el centro de la plataforma WPF estaba bajo construcción. Muchos aspectos de WPF, el modelo look-less control y data templates, utiliza la fuerte separación de la visualización, del estado y comportamiento promovido por MVVM.
El único aspecto importante que hace MVVM un gran patrón para WPF es el uso de la infraestructura de enlace de datos. Enlazando propiedades del ViewModel a la view, obtenemos bajo acoplamiento entre los dos y quita la necesidad de escribir código en el ViewModel para actualizar directamente la view. El sistema de enlace de datos también soporta validación de ingreso de datos, el cual provee un modo estandarizado de transmitir errores de validación a la view.
Otras dos características de WPF que hacen este patrón tan útil son los data templates y el sistema de recursos. Data templates aplican Views a los objetos ViewModel que se muestran en la interfaz de usuario. Podemos declarar plantillas en XAML y dejar al sistema de recursos automáticamente localizar y aplicar estos templates por nosotros en tiempo de ejecución.
Si no fuera por el soporte de comandos en WPF, el patrón MVVM seria manos poderoso. En este artículo les mostrare como un ViewModel puede exponer comandos a una View, permitiendo a la vista consumir su funcionalidad. Si no estás familiarizado con commanding, recomiendo la lectura del artículo de Brian Noye’s, "Advanced WPF: Understanding Routed Events and Commands in WPF".
Además de hacer las características de WPF SILVERLIGHT un modo natural de estructurar una aplicación, el patrón es también popular porque las clases ViewModel son fáciles de hacer test unitarios. Cuando la lógica de interacción de la aplicación vive en un conjunto de clases ViewModel, podemos escribir fácilmente código que lo testea. En un sentido, Views (vistas) y test unitarios son dos tipo distintos de consumidores del ViewModel. Teniendo un framework de test para un ViewModel de una aplicación da la posibilidad de hacer test de regresión, el cual ayuda a reducir el costo de mantenimiento de la aplicación en el tiempo.
Promoviendo la creación de test de regresión automático, la testeabilidad de las clases ViewModel pueden asistir en diseñar apropiadamente interfaces de usuario.
Cuando estamos diseñando una aplicación, podemos a menudo decidir si algo va en la view o en el ViewModel. Si podemos escribir test unitarios para el ViewModel sin crear un objeto UI, podemos también encarnar el ViewModel porque no tiene dependencias en los elementos de la vista.
Como último, para los desarrolladores que trabajan con diseñadores visuales, utilizar MVVM hace mucho más fácil para crear un workflow suave en términos diseñador/desarrollador. Ya que la view es un consumidor arbitrario de un ViewModel, es fácil quitar una vista y colocar una nueva vista para visualizar el ViewModel. Este simple paso permite realizar prototipos rápidos  y una evaluación de interfaces usuario hecha por los diseñadores.
El grupo de desarrollo puede focalizarse en crear clases robustas ViewModel, y el grupo de diseño puede focalizarse en hacer views amigables con el usuario. Conectando el resultado de los dos grupos puede involucrar poco más que asegurar que existen los correctos enlaces en el archivo XAML de la vista.
En la próximo post, explicamos la aplicación Demo.


miércoles, 18 de mayo de 2011

Segregacion de Responsabilidades de Comando y Consulta (CQRS)


Command and Query Responsability Segregation (CQRS)
Fue casi un año desde que lei el libro azul (Domain Driven Design; Tackling complexity in the Heart of Software). Cambio mi visión de como escribo el software y como construir arquitectura del software. Durante el tiempo de desarrollador, intente muchos enfoques distintos en la creación del software. Un montón de enfoques incluyen un modelo de dominio anémico. No hay nada malo en construir un modelo de dominio anémico. Un modelo de dominio anémico es un término utilizado que describe el uso de un modelo de dominio de software donde la lógica de negocio esta implementada fuera de los objetos de dominio. La lógica esta típicamente implementada en clases separadas que transforman el estado de los objetos de dominio. Este patrón es un enfoque común en aplicaciones empresariales .NET siguiendo la arquitectura de aplicaciones de servicios de tres capas, donde los objetos caen dentro de la categoría de “Business Entities” entidades de negocios (aunque entidades de negocios puede también contener comportamientos).
Para aplicaciones con lógica de negocios mas compleja, puede que no sea la mejor opción. Terminamos con un montón de lo que se dice código espagueti con alto nivel de acoplamiento entre las distintas partes del código. Modelos de dominio anémicos tienen su lógica de entidades distribuidas por todo el código y generalmente tenemos que actualizar varias partes en el código si una regla de negocio cambia. Tengamos esto  en mente cuando codificamos.
Siempre codifiquemos como si el tipo que termina manteniendo el código será un psicópata violento que sabe dónde vivimos.
Un modelo de dominio rico clásico tiene toda la lógica de negocio dentro del modelo y la mayoría de los objetos están conectados unos con otros. Se esfuerza por ser un modelo que resuelve la lógica del dominio para el negocio en un modelo perfecto. Y es aquí donde este modo de escribir software falla. Obtenemos un gran modelo que finalmente se pone muy pesado.
 Divide el modelo
En lugar de tratar de resolver todo en un modelo, divídelo en pequeñas partes y trabaja con cada porte. Crea agregados que naturalmente encajen juntos. Un ejemplo puede ser un auto y un cliente. En este ejemplo, ambos son agregados raíces. Debería considerar no modelar ambos objetos y sus agregados en un modelo. Pensemos en ellos como pequeños modelos separados dentro del modelo. Esto hará el modelo mucho mas fácil de manejar cuando persistimos o cargamos en memoria.
El problema con bases de datos relacionales
En estos días muchos usamos ORMS para persistir datos de un modelo de dominio en la base de datos, y utilizan una base de datos relacional como base de datos. El problema con las bases de datos relacionales es que tenemos que hacer un compromiso con la velocidad de lectura y la velocidad de escritura. Si normalizamos la base de datos, será mejor para los casos como insertar, actualizar, y eliminar pero no leyendo datos. Los problemas son los índices. Ellos en la mayoría de los casos bajaran el rendimiento de las operaciones de selección de datos, pero ayudan en operaciones para insertar, eliminar y actualizar. Tenemos que hacer un compromiso, leer rápido o escribir rápido.
Si decidimos hacer la base de datos mejor para la lectura de datos (select), una opción es de- normalizar la base de datos, Una base de datos de-normalizada significa tablas con datos repetitivos y posiblemente tablas con un gran número de columnas.
Como nosotros desarrolladores no damos mucha importancia a esta pregunta, como escalar la solución. Creo que tenemos que tener este pensamiento en nuestra cabeza cuando creamos una solución que puede servir muchos usuarios.
Command and Query Responsability Segregation.
La mayoría de las aplicaciones lee datos mas frecuentemente que cuando escriben. Basados en esto, sería una buena idea hacer una solución donde podemos agregar más bases de datos para la lectura, ok? ¿Entonces si establecemos una base de datos dedicada a la lectura? ¿Aun mejor, que pasa si diseñamos una base de datos de modos que sea rápida para la lectura? Si diseñamos nuestra aplicación basadas en CQRS, tendremos una solución es escalable para la lectura de datos. Command Query Separation es un patrón que fue introducido por Bertrand Meyer.


Un rápido paso a paso por la arquitectura CQRS


Una vista grafica de la arquitectura. Un usuario abre una aplicación y la primera pantalla se carga. Los datos son lanzados desde el lado consulta. En este ejemplo va a través de un servicio WCF y utiliza, digamos NHibernate para cargar datos desde la base de datos y dentro del DTO que retorna los datos a la GUI. El DTO esta modelado para que encaje en la pantalla que esta visualizando el usuario. La base de datos de consulta es a menudo de-normalizada para mejorar las lecturas. El usuario puede navegar por las distintas pantallas, y el proceso es el mismo. Un DTO modelado para la pantalla del usuario es devuelto por la base de datos. Eventualmente, el usuario quiere cambiar los datos en una de las pantallas. Lo que sucede es que un mensaje del lado Command es creado basado en los datos que han cambiado en la vista y envidaos por el lado izquierdo de la figura, el lado Command. El mensaje comand es enviado dentro del modelo de dominio para ser validado contra las reglas de negocio. Si el mensaje pasa a través del modelo sin errores, es salvado en la base de datos de escritura y sincronizado con la base(s) de lectura. El lado de Command nunca debe retorna otro dato que no sea un mensaje de error. Si seguimos esta regla, el lado del comando será solo comportamental. Esto hace muy fácil loggear que sucede en el modelo de dominio, y es fácil seguir lo que quiso hacer el usuario, no solo cuales fueron los resultados de sus acciones. Este enfoque puede ser también utilizado en una aplicación ya existente (Brown field) sin mucho cambio de la arquitectura, solo tenemos que agregar el lado de consulta a la arquitectura vieja.
¿Porque agregar DTOS del lado de la consulta?
En un modelo de dominio tradicional, crearemos objetos para resolver lógica del dominio, no para visualización. Tienen comportamiento en lugar que forma. Para hacer los objetos de dominio mas visualizables, muchos desarrolladores utilizan mapeos entre el modelo de dominio y los DTOs modelados para visualización. Esto resulta en una gran cantidad de mapeos entre objetos para el desarrollador y modelos del dominio que exponen getters y setters.
Si estamos utilizando ORMs como NHibernate, tenemos que agregar getters al modelo de dominio y yo pienso que asi esta bien. El modelo esta aun protegido contra cambios no deseados que puede hacerlo invalido. Cada cambio debe suceder a través de los métodos Command.