Archive

Posts Tagged ‘MVVM’

Retrospectiva sobre MEF: usos en el mundo real

April 11th, 2011 No comments

Evaluación de diferentes formas en las que el autor ha usado MEF para mejorar la arquitectura de varias aplicaciones de negocios a gran escala en las que ha estado envuelto. Desde el manejo de valores de configuración, hasta la administración de vistas y regiones modulares, pasando por mensajería y uso de comandos, Jeremy Likness ha usado MEF para crear aplicaciones flexibles y extensibles en Silverlight.

 

Este artículo fue publicado originalmente en Maromas Digitales y es una traducción aproximada del artículo MEF in the Wild: A Retrospective publicado en inglés por Jeremy Likness el 27 de setiembre del 2010 en su blog C#er:Image.

 

Luego de haber trabajado en varios proyectos grandes usando la Infraestructura de extensibilidad administrada, me parece buena idea compartir mis experiencias en cómo lo usamos y las ventajas que nos dio. Las siguientes son diferentes formas en las que MEF nos ayudó a crear aplicaciones modulares en Silverlight .

A diferencia de mi artículo anterior titulado Diez razones para usar MEF, este es más un catálogo de casos específicos usando MEF en proyectos reales.

 

Inversión de control e inyección de dependencias

Esta fue probablemente la decisión más fácil. Ninguno de los proyectos necesitaba un mecanismo de inversión de control (IoC) o inyección de dependencias más sofisticado que el ofrecido por MEF. Ya que de todos modos íbamos a usarlo por otras razones, y además viene incluido en la plataforma .NET, nos pareció lógico usarlo para resolver este problema. En la mayoría de los casos bastó con simplemente declarar una interfase, exportarla donde es implementada e importarla donde fuese necesario. Describo a continuación otros casos más específicos.

 

Configuración

Para nosotros fue muy importante el manejo de los datos de configuración y MEF nos hizo la tarea fácil. La razón por la que lo menciono en esta categoría es por ser, en realidad, un efecto secundario de la inversión de control. Mediante definir una interfase es posible que sea usada por el resto de código; además, en la etapa de prueba los valores de configuración pueden ser fácilmente simulados. El servicio principal de la aplicación implementa la configuración y usa una combinación de constantes definidas durante la compilación y otros parámetros para cargar los valores. Los consumidores en cualquier parte de la aplicación, incluso si son módulos cargados de forma dinámica y sin tener referencias concretas a al ensamblaje donde reside el mecanismo de configuración, tan sólo necesitan importar la interfase para tener acceso a los valores.

 

Registros de historial

El patrón IoC implementado en MEF también nos ayudó de forma indirecta a implementar un registro de historial. Lo que hicimos fue crear una interfase implementada por un registro de historial y acostumbrarnos a usarlo en vez de Debug.WriteLine, con la ventaja de poder indicar el grado de severidad, la fuente del evento y otros datos auxiliares. Al separar las funciones de este modo pudimos usar al principio un mecanismo simple de registro (por ejemplo, escribir en la ventana de depuración) con la flexibilidad de poder añadir más adelante otros mecanismos como almacenaje aislado, llamadas a otros servicios, y así por el estilo. Así simplificamos el manejo de transacciones desde un punto central sin tener que alterar el resto de la aplicación.

 

Administración de regiones

Antes que nada quiero aclarar que Prism 4.0 posee una excelente infraestructura para el manejo de regiones y no tengo nada en su contra ni es mi intención reinventar algo ya existente. Lo que pasó es que nuestro proyecto tenía sólo unas pocas regiones especificadas por lo que era mejor usar algo más liviano.

El manejo de regiones se compone esencialmente de unos cuantos componentes. Tenemos una interfase que sirve como adaptador para las regiones y que admite clases de tipo contenedor (como Grid o ContentControl y demás). Para crear nuevos adaptadores basta con heredar la interfase, agregar la información adicional de exportación para describirle a MEF el contenedor con el que es compatible, y luego crear eventos como el registro (apuntar la vista a una región), activación (hacer que la vista aparezca en la región) y desactivación (remover la vista). A veces tuvimos que manipular el contenido, o algunos de los elementos secundarios, pero en general el administrador de estados visuales (Visual State Manager) se encarga de esa tarea.

El contenedor es definido como una región usando una propiedad adjunta y cada vista contiene metainformación describiendo a cuál región ha de ser asignada. El administrador de regiones agrupa y coordina todos estos componentes. Si necesito activar una vista, el administrador de regiones usa el patrón de cadena de responsabilidades para encontrar el adaptador de la región a la que pertenece la vista y luego le pide que la despliegue.

 

 

El artículo Usando MEF en vez de Prism – Parte 2 da una explicación detallada sobre el manejo de regiones. También pueden ver el artículo en inglés Advanced Silverlight Applications using MEF para una infraestructura de muestra.

 

Integración de servicios

Es común que en aplicaciones empresariales hayan diferentes modelos u objetos del dominio del problema a resolver que comparten operaciones de datos. Por ejemplo, su creación, actualización, borrado y consulta. Por esta razón, pude crear una interfase abstracta IServiceFor<T> que define operaciones de este tipo. Las implementaciones de la interfase son exportadas de manera explícita y el direccionador de servicios se encarga de asignarlas a las entidades correspondientes.

Esto quiere decir que puedo crear un modelo de vista para una entidad, y simplemente solicitar al direccionador de servicios que me provea un servicio que ofrezca las operaciones genéricas, sin tener que preocuparme de cómo fue implementado el servicio. Se hace fácil entonces simular los servicios mientras se desarrollan las operaciones en sí. Por ejemplo, algunos servicios usaron el almacenamiento aislado mientras que otros enviaban mensajes por la red, pero a fin todos fueron desacoplados del modelo de vista y agrupados por MEF.

 

 

Mensajería

Otro aspecto importantísimo en cualquier sistema es la mensajería. Por ejemplo, imaginen que tenemos un modelo de vista que ofrece filtrado de datos y que puede ser usado por otros modelos de vista. ¿Cómo pueden enterarse estos otros modelos de vista cuando cambia la especificación del filtro, o cómo pueden obtener el filtro en sí?

En este proyecto lo hicimos de dos formas.

 

Composición de vistas

Aunque sea aplicado de manera global, un filtro puede ser considerado como parte del modelo de vista que lo use. Si bien por sí mismo no es de utilidad, al añadirlo como un componente de otro modelo de vista puede entonces ser usado en ese contexto. MEF fue muy útil para aplicar este patrón ya que cualquier modelo de vista que necesite usar otro no más necesita importarlo:

 

 

Por supuesto, todavía no podemos saber cuando el filtro ha cambiado a menos que nos suscribamos al evento de propiedad cambiada. Puede que eso sea razonable algunas veces, pero hay otras en que un mensaje de ese tipo es lo suficientemente importante como para que varios componentes necesiten escucharlos. Para ese fin usamos el patrón agrupador de eventos.

 

Agrupador de eventos (EventAggregator)

Mi versión del agrupador de eventos se basó en un artículo que describe una implementación basada en extensiones reactivas (RX). Le hice algunas modificaciones para que fuera compatible con Silverlight y trabajó de maravilla.

Otro caso común fue usar mensajes para causar cambios en la aplicación. Por ejemplo, para avisar sobre un nuevo filtro o una nueva selección por parte del usuario. Para eso hice una clase dedicada a difundirlos, llevando cuenta del tipo, el mensaje y una enumeración. De esa manera, si quiero anunciar una nueva selección entonces puedo crear una instancia de esta clase e insertar el elemento elegido junto con su tipo y usar la enumeración para indicar que es “select” para luego publicar el evento.

Quien esté interesado en este tipo de mensaje puede entonces escucharlo de esta manera:

 

 

 

Direccionamiento XAPs modulares

El hecho de que las aplicaciones de Silverlight son transferidas a través de la red y almacenadas en la máquina del usuario hacen que el cargado dinámico de módulos XAP sea de gran importancia. Hay dos razones principales: el tiempo de descarga y la cantidad de memoria requerida en el cliente. Mediante usar cargado dinámico, podemos fragmentar la aplicación en módulos XAP y diferir su uso hasta que sean necesarios. Como resultado, se reduce el tiempo inicial de carga de la aplicación y la memoria requerida al principio.

Un reto que experimentan algunas bibliotecas es cuándo y cómo iniciar el cargado del módulo. Por mi parte, yo prefiero un método al que he llamado “direccionamiento dinámico de XAPs.” Es una idea sencilla: asignar etiquetas a las vistas, ya sea usando nombres explicativos o el espacio de nombres completo.  En mi proyecto principal, donde radica la infraestructura, tengo un conjunto de constantes globales que representan las diferentes vistas.  Aunque el módulo no sabe nada sobre la vista, las constantes sirven para referirse a ella. Otro conjunto de constantes describen los archivos XAP disponibles.

Con estas dos pistas puedo entonces usar un servicio de inicialización que encamine de manera dinámica los módulos usando catálogos de distribución para cargarlos. Una ruta de direccionamiento apunta hacia la vista y el archivo XAP que la contiene y es exportada para uso de cualquier componente que necesite cargarla. Cuando se solicita una vista, el administrador de regiones verifica que exista la ruta correspondiente y luego le pide al servicio de direccionamiento que cargue el archivo XAP, demorando la navegación a la vista hasta que haya sido cargada. Esto hace fácil separar la navegación de los módulos, haciendo posible que cualquier área de la aplicación solicite vistas, mientras que la infraestructura se preocupa de cargar los módulos necesarios y proveer las rutas requeridas.

 

Direccionamiento de modelos de vista

Un problema común en MVVM es cómo atar el modelo de vista a la vista. Ninguna de las bibliotecas que he usado provee correlaciones uno-a-uno entre ambos debido a que a veces un modelo de vista sirve a varias vistas. Aunque las vistas dependen de él (se le puede considerar como el contrato de ligado de la vista), el modelo de vista no sabe nada sobre las vistas a las que está asociado. Las vistas son exportadas a la región de destino usando su tipo o con una etiqueta, de igual manera que los modelos de vista son exportados con una etiqueta.

Las rutas son implementadas con un simple objeto que contiene dos etiquetas, una para la vista y otra para el modelo de vista. Ya sea que la vista exporte la etiqueta o que lo haga una clase para direccionamiento, la exportación es al final manejada por un direccionador centralizado. Este direccionador es capaz de extraer vistas y, como todo es cargado de manera diferida, puede determinar si la vista necesita ser atada al modelo de vista. Por otra parte, también provee una referencial al modelo de vista que, por cierto, es creado si es la primera vez que se usa.

El resultado es que la asociación entre la vista y el modelo de vista es completamente desacoplada, y es descrita en otra parte de la aplicación. También significa que el sistema de enrutamiento conoce cuando una vista está siendo desplegada por primera vez de manera que puede llamar métodos de inicialización en el modelo de vista tanto al ser creada como cuando es activada posteriormente. Esto permite que mis vistas reaccionen a cambios o mantenimiento que sea necesario antes de ser desplegadas de nuevo sin tener que depender de la jerarquía visual.

 

 

Para más detalles pueden ver los artículos Atando el modelo de vista con MEF (en inglés) y Otro patrón de localización de modelos de vista.

 

Desacoplando las vistas

Hay situaciones en las que es necesario hacer referencia a un tipo específico de vista que no es conocida de antemano. Por ejemplo, puede que una infraestructura de navegación dependa del tipo de vista (como en la sección siguiente). Cuando la vista se encuentra en un XAP que todavía no ha sido cargado, no hay manera de obtener una referencia directa a la vista. En este caso, MEF fue muy útil para manipular tipos diferidos, es decir, es posible importar una propiedad de un tipo especifico usando tan sólo una etiqueta (como “MainView” o “DashboardView”) y exportar esa etiqueta en otra parte. Así pudimos separar completamente la interacción con la vista y su tipo.

 

Navegación

MEF provee una infraestructura de navegación muy flexible. Lo que yo quería es un tipo de navegación capaz de entender entidades compuestas, de manera que un evento de navegación no estuviese limitado a páginas en la aplicación sino más bien a vistas, incluso cuando hay vistas dentro de otras.

La navegación coopera con el direccionador de modelos de vista para estar al tanto de cambios en estos últimos. En la infraestructura que desarrollé, el agrupador de eventos basado en MEF simplemente genera un evento de navegación de vista que encapsula el tipo de la vista y un indicador de activación o desactivación. El direccionador, que ha importado todas las vistas y modelos de vista, encuentra la vista y se comunica con el administrador de regiones para activarla o desactivarla. Si es activada entonces también llama el método correspondiente de inicialización en el modelo de vista.

Al generalizar cuadros de diálogo, páginas, y hasta asistentes (Wizards) dentro del concepto de eventos navegación, la tarea se hace increíblemente simple. En este contexto, el que una ventana sea emergente es tan sólo un detalle de implementación independiente del evento en sí, y el modelo de vista simplemente solicita que se navegue a esa vista sin tener que preocuparse de modelos, regiones, o ningún otro detalle propio de la navegación.

 

Autorización

La mayoría de las aplicaciones de negocios requieren servicios de autenticación y autorización. Por lo general, el usuario tiene propiedades como roles y credenciales que son verificados a la hora de obtener acceso a diferentes partes de la aplicación. MEF hace fácil el difundir las credenciales ya que el el usuario puede ser exportado como un objeto concreto, o como una interfase, y luego importado o consultado por las áreas de la aplicación que requieran saber el nivel de autorización.

 

Comandos

Los comandos pueden ir desde los que están fuertemente entrelazados con la interfase al usuario, hasta los que son tan independientes que pueden residir en módulos aún no cargados. Por ejemplo, comandos como volver al inicio (“home”) o expandir requieren eventos de navegación que conozcan la vista de destino.

 

Comandos de enlace diferido

El mecanismo de exportación e importación de MEF nos ayudó a implementar este tipo de enlace, también conocido como enlace tardío. En algunos casos el modelo de vista importa el comando usando una etiqueta predeterminada (por ejemplo “home”) aun si la vista se encuentra en un módulo diferente. Cuando es cargado, el módulo exporta el comando haciéndolo disponible para ser enlazado al modelo de vista. De esta manera es diferido, pues el comando no se puede usar hasta que el módulo que lo contiene es cargado.

 

 

Comandos globales

Hay otros comandos que son de naturaleza general, por lo que es mejor crear una sola implementación global en vez de duplicarlo por todas partes. Los comandos globales pueden ser exportados y luego importados donde sean necesarios, de manera que una copia única es usada, en vez de múltiples instancias locales. Usando de nuevo el ejemplo “home”, los modelos de vista pueden ofrecer ese servicio a la vista sin conocer el módulo o ensamblaje que contiene su implementación dejando que MEF importe el comando cuando ya está disponible.

Para más detalles pueden consultar el artículo Sharing Commands with MEF.

 

Cadena de responsabilidades

El patrón cadena de responsabilidades es una poderosa herramienta para administrar mensajes comunes que son procesados de manera diferente dependiendo de sus características. En este caso, usé MEF para proveer un mecanismo de administración que define un contrato o interfase estándar que consume ciertos tipos específicos de mensajes. Cada administrador exporta el contrato junto con metainformación describiendo el tipo de mensajes con los que es compatible. Un enrutador central se encarga de importar los administradores y escuchar los mensajes despachándolos a los administradores apropiados hasta que alguno responda diciendo que lo pudo procesar correctamente. En combinación con los comandos globales, este mecanismo provee un alto grado de extensibilidad a la aplicación.

Por ejemplo, imaginemos un comando “imprimir” que está disponible a toda la aplicación pero está enlazado al elemento que va a ser impreso. Hay varios controladores que han exportado el contrato de impresión y que saben cómo manejar distintos tipos de datos. Cuando el controlador que maneja el objeto de destino es invocado, formatea la información para poder ser impresa y envía el resultado a la impresora. Para manejar un nuevo tipo de datos, basta con crear un nuevo controlador y exportar el contrato o interfase de impresión.

 

Fábricas de clases con resolución de dependencias

Gran cantidad de clases tienen dependencias en varios niveles. Un caso puede ser una vista compuesta donde se presenta una lista de artículos, y cada artículo es expuesto mediante un modelo de vista asociado que tiene dependencias en el agrupador de eventos, el bus de servicios, y otros contratos que son importados usando MEF. Tal escenario es simplificado gracias a ExportFactory. Con esa herramienta se puede crear un modelo de vista con todo y resolución de dependencias, mientras iteramos una lista de datos. Los datos son incorporados al modelo de vista y éste es enlazado con la vista correspondiente; en todo esto, MEF se encarga de resolver las dependencias.

 

Vistas compatibles con la fase de diseño

Si se trabaja en paralelo con un equipo de diseñadores, es sumamente importante tener vistas que se comporten adecuadamente en la fase o tiempo de diseño. Es fácil crear vistas que pueden ser asociadas con modelos de vista diferentes durante la etapa de diseño usando los atributos d:Design y d:DesignInstance, mientras que MEF asocia el modelo de vista real durante la ejecución. Para este fin se puede usar la interfase IPartImportsSatisfied, evitando que en las vistas y modelos de vista se invoque código destinado al tiempo de ejecución.

Para más detalles pueden ver el artículo (en inglés) Usando MEF para crear modelos de vista compatibles con la fase de diseño.

 

Motor de validación

Los motores de validación por lo general exponen formas de verificar si se han violado reglas específicas. Con MEF fue fácil crear un mecanismo de validación flexible y extensible, exportando un contrato de uso para cada regla de validación. El motor entonces importa todas las reglas y provee acceso usando una interfase fluida. Pueden leer el artículo (en inglés) Validación fluida con MEF y PRISM para más detalles.

 

Pruebas unitarias

MEF fue de importancia crítica en nuestro éxito con las pruebas unitarias, principalmente por exponer como contratos todas las dependencias importadas. Durante las pruebas lo que hicimos fue no invocar a MEF, dejando que el sistema fuera inicializado usando componentes simulados o parciales.  Más información en el artículo (en inglés) Pruebas unitarias avanzadas en Silverlight usando Moq.

 

Conclusión

Obviamente muchos de estos ejemplos podrían ser implementados usando otras herramientas aparte de la Infraestructura de extensibilidad administrada. Una ventaja de MEF es que viene incluida en la plataforma de ejecución: no es una biblioteca provista por terceros, sino que es parte fundamental de .NET y de Silverlight 4.0. Basándome en mi experiencia al diseñar varias aplicaciones de gran escala en Silverlight, diría que MEF no sólo facilitó el hacerlas modulares, sino que también, al incluir tantas utilidades, redujo el tiempo de desarrollo. En especial con la habilidad de etiquetar los componentes exportados con metainformación y poder importar múltiples componentes usando el mismo contrato. Espero que esto les ayude con algunas ideas sobre cómo usar MEF en sus propias aplicaciones, y que también sirva para demostrar de que MEF está siendo usando con gran éxito en la producción de aplicaciones empresariales.

 

Jeremy Likness

 

Categories: MVVM Tags: , ,

DataGrid, ColumnSeries y un toque de MVVM

March 17th, 2011 12 comments

image

Recibí una pregunta pregunta en un post que había escrito previamente. La pregunta era como se puede cambiar una gráfica a la par con los datos de un DataGrid. La respuesta es ¡Con DataBinding!

Muchas gracias.

Ok ok, la explicación larga. Primero vamos a hacer un modelo para datos de prueba:

 

Este modelo cuenta con dos propiedades (Name y Value) e implementa INotifyPropertyChanged para poder manejar el Binding de forma correcta.

Ahora creamos el ViewModel. En una aplicación real deberías obtener dichos valores desde un webservice en tu servidor, pero para efectos prácticos, aquí inicializo una lista de objetos SampleData (nuestro modelo) en el constructor del ViewModel.

 

Finalmente creamos nuestra vista en XAML:

 

En la línea 13 creamos una instancia de nuestro ViewModel y la agregamos a nuestros recursos locales. Después, en la línea 17 asignamos dicho recurso al DataContext de nuestro LayoutRoot (en este caso el Grid que contiene todos los elementos de la vista). En la línea 30 definimos la propiedad Samples de nuestro ViewModel como la fuente de datos del DataGrid. En la línea 40 definimos el binding a la propiedad Value con un slider para modificar los datos fácilmente. Las líneas 55 y 57 se encargan de hacer lo mismo para la gráfica de barras.

Nótese como los bindings se definien con el Mode=TwoWay para actualizar el ViewModel “de ida y vuelta”, es decir, que los cambios en la vista se reflejan en el ViewModel y viceversa.

Puedes ver el ejemplo corriendo aquí. Y puedes descargar el código aquí.

UPDATE: De pura casualidad encontré mi compañera Araceli Medina encontró un bug en el Silverlight Toolkit mientras jugaba con el demo. Estaba jugando con mover sliders y cambiar el tamaño de la ventana cuando noté que esto pasaba:

image_thumb[2]

El borde inferior de los rectangulos no se quedaba en la parte de abajo de la gráfica. No estoy seguro a qué se deba esto pero si se vuelve a cambiar el tamaño de la ventana el problema se corrije. El bug fue dado de alta en codeplex.

[Artículo originalmente publicado en JAMolina.com]

Tutorial Silverlight 4 – Proyecto MVVM con Ria Services multi capa

February 9th, 2011 4 comments

De vuelta con nuestros tutoriales semanales de Silverlight 4.

He navegado muchos sitios y foros de desarrolladores Silverlight buscando la respuesta a la pregunta: ¿Es posible crear un proyecto RIA Services con más de dos capas? Hace unos meses me encontré con un sitio donde mostraban una metodología para lograrlo. La verdad es que hoy en día (y gracias a mi descuido) he perdido la referencia a ese sitio. Sin embargo, el conocimiento quedó conmigo ya que lo uso contínuamente en diferentes proyectos Silverlight que desarrollo. Para mí, es momento de compartir de nuevo este conocimiento como me ha sido compartido y aprovecho para agregarle el toque MVVM.

¿De qué me serviría crear un sitio RIA Services con más de dos capas? Bien, la respuesta depende de la necesidad de cada proyecto. Yo en mi caso lo uso más o menos así:
Solución VS 2010
1. Proyecto Web con el Domain Service, Modelo y Conexión BD
2. Proyecto Librería Silverlight que será quien esté conectado a los RIA Services del Proyecto Web
3. N Proyectos Ejecutables de Silverilght que consumen los datos a través de los RIA Services que provee el Proyecto Librería

Ahora bien, yo en mi caso lo uso así, pero si tu tienes una aplicación Silverlight dividida en módulos es razonable querer tener acceso a los datos a través de todos los módulos de tu aplicación estén o no en el mismo .xap. Tener una librería Silverlight externa con conexión a RIA Services te permite separar este caso en un .xap independiente y consumir estos datos desde cualquier otra librería .xap o ejecutable Silverlight.

Después de esta introducción los dejo con el video tutorial en el que te explico como hacer este procedimiento. Te pido disculpas con anticipación pro la calidad del audio del video. Estoy trabajando en mejorar mis condiciones de grabación.

Los temas cubiertos en el video son:

  • Partiremos de una solución VS 2010 vacía.
  • Crearemos una aplicación web con un modelo, conexión a base de datos y servicios RIA.
  • Crearemos una librería Silverlight que consumirá los RIA Services
  • Terminaremos con un proyecto ejecutable de Silverlight con MVVM que servirá como cliente.

Para ver el video y bajar el código de ejemplo ve a alFador en punto net

Técnicas con MVVM

February 4th, 2011 No comments

Uno de los obstáculos que he notado en muchos (incluyéndome a mí) tratando de entender MVVM, es aceptar que no es una receta, sino un concepto. Estamos acostumbrados a buscar procedimientos reproducibles que nos lleven, paso a paso, a la solución. Desafortunadamente (o por dicha, según uno lo vea), MVVM no se presta a tal formato.

El patrón de diseño Modelo-Vista-Modelo de vista es más una estrategia, una idea general de cómo estructurar la solución a un problema. En vez de listas de pasos, necesariamente lo que encontramos son explicaciones de los componentes principales del patrón y algunos ejemplos de su aplicación. Para los que todavía no están familiarizados con el patrón, Jeremy Likness ha escrito una muy buena introducción al tema.

 

Estrategia y táctica

Si bien la estrategia a utilizar es esencial, las tácticas son las que ponen en acción el plan principal. En una batalla, la estrategia puede ser ocupar cierta zona para avanzar en el territorio enemigo, pero la forma en que las fuerzas son distribuidas o los diferentes ataques individuales forman las tácticas del enfrentamiento.

En MVVM, la estrategia es dividir la solución en ciertas zonas o capas como el modelo, la vista, y el pegamento entre ambas: el modelo de vista. Las tácticas incluyen, entre muchas otras, la navegación entre vistas, el envío de datos del modelo a la vista, la comunicación entre la vista y el modelo de vista, el uso de comandos y así por el estilo.

Aunque MVVM no se presta a recetas premeditadas, sí hay gran variedad de técnicas o tácticas que pueden ser usadas en su aplicación al problema y que pueden ser bien definidas en procedimientos concretos. Por ejemplo, en las últimas semanas he estado publicando traducciones de algunos artículos que proponen métodos para resolver el problema de la asociación entre vistas y modelos de vista y el manejo de transacciones en la interfase gráfica de la aplicación.

La ventaja del sistema completo, estrategia y técnica, es que podemos escoger las que mejor se adapten a nuestras circunstancias particulares o, siendo francos, a nuestro gusto. Los siguientes artículos muestran algunas formas de resolver problemas comunes enfrentados al implementar MVVM. Los invito a leerlos y escoger los que les parezcan apropiados, elegantes, efectivos, o cualquier otro aspecto que les llame la atención.

 

 

Categories: General Tags: ,

Tutorial Silverlight 4 – Instalación del Framework MVVM Light

February 1st, 2011 1 comment

Bienvenido de nuevo.

En este video tutorial te explicaré paso a paso el proceso de instalación del Framework MVVM Light. Éste Framework es desarrollado por Laurent Bugnion en Suiza y está enfocado en permitir de un modo simple el desarrollo de aplicación WPF y Silverlight (incluído WP7). El principal enfoque que tiene éste Framework es el de ser amigable con Expression Blend por lo que te permite desarrollar aplicaciones a través de la interfaz gráfica de Blend.

Los temas cubiertos en el video son:

  • Presentación corta del Framework MVVM.
  • Donde encontrar recursos, documentación y los archivos de instalación.
  • Guía paso a paso de la instalación en Visual Studio 2010 y Expression Blend.
  • Creación de un proyecto MVVM Light para probar la instalación del Framework

PARA VER EL VIDEO TUTORIAL VE A: alFador en punto NET

¿Por qué usar MVVM?

May 29th, 2010 2 comments

Recuerdo hace unos quince años, cuando la fiebre de la Internet estaba todavía en pañales y las ferias comerciales de software eran gigantescas, decidí ver la demostración de un nuevo producto de Borland: Delphi. La idea de crear aplicaciones mediante arrastrar controles a una ventana y escribir pequeños trozos de código alambrando las funciones como si fueran un mecano o un lego me dejó fascinado. Acostumbrado a usar infraestructuras como MFC y OWL, el nuevo sistema parecía revolucionario.

Poco después ya estaba yo usando el nuevo juguete para crear aplicaciones en mi lugar de trabajo. De igual manera, no tomó mucho tiempo para percatarme que los ejemplos que había visto en la feria estaban cuidadosamente planeados y daban una impresión incorrecta. Tan pronto como uno quería crear algo más complejo que un par de botones y campos de entrada, el código subyacente comenzaba a crecer y hacerse difícil de controlar.

Tras una pausa de varios años en la que estuve envuelto exclusivamente en el ámbito de Linux, volví a Windows esta vez usando Visual Studio y C#. Sin embargo, encontré que la práctica de usar  las ventanas (Windows Forms) como los módulos de la aplicación todavía seguía en vigencia. Aún ahora, no es raro encontrar clientes con aplicaciones que tienen ventanas con 3000 o más líneas de código subyacente.

¿Es eso malo? Aunque personalmente no me gusta tal estilo de programción, no creo que sea malo o bueno. Mientras funcione, ¿qué importa? Por supuesto, la manutención del proyecto puede ser un reto. Especialmente si los desarrolladores originales ya no están disponibles. Aunque no hay clausulas goto en el código, definitivamente es una bola de espagueti.

“Yo diseño el programa mientras lo escribo”

Será por lo fácil que es sentarse simplemente a escribir código que muchos tendemos a ni siquiera tener una idea nebulosa de lo que queremos conseguir cuando ya estamos creando una interfase gráfica y escribiendo código subyacente. Como dice Steve McConnell, es como si al querer construir una casa, comenzáramos a erigir el edificio sin ningún plan determinado, simplemente poniendo juntos los materiales y dejando que la forma de la casa, con todos sus detalles vaya surgiendo poco a poco. La analogía muestra el poco sentido de tal estrategia. Para construir un edificio hay que tener al menos un plan general de la distribución de los cuartos o habitaciones de la casa. Algunas decisiones tienen serias repercusiones en el resultado. ¿Será una casa con una o dos plantas? La estructura básica es diferente en cada caso.

A veces he oído a algunos decir que es más bien como una pintura o escultura, donde el artista deja que su medio le vaya sugiriendo le dirección a seguir. Pero aún así, un artista tiene una noción de lo que intenta producir. Antes de poner óleo en la lona o clavar el cincel en el mármol, el artista tiene un boceto en papel o en su mente. Si el producto deseado es un retrato o un busto, y termina con una pintura o escultura de un caballo, algo anda mal. Por más que el artista diga que es lo que su inspiración le dictó (o lo que el mármol le pidió), el cliente no va a estar satisfecho con ser percibido en términos equinos.

Bocetos en software

Volviendo a mi enamoramiento inicial con Delphi (y C++ Builder), por ese tiempo también salió un libro que eventualmente se convirtió en un clásico: Design Patterns: Elements of Reusable Object-Oriented Software. Si bien no es revolucionario, sí es especial por definir en forma concreta estrategias específicas para implementar algunos tipos de soluciones a problemas que aparecen repetidamente en la creación de aplicaciones. Desafortunadamente, el tono no es exactamente como el de un libro de Stephen King, lo que dificulta un poco su lectura. Por dicha, a través de los años han surgido otros volúmenes con un enfoque más asequible a los que somos simples mortales.

En fin, los patrones de diseño no son exactamente procedimientos o recetas para la creación de software, sino más bien bocetos a grandes rasgos de la forma general que puede tomar una solución a un problema específico. Nótese el gran número de términos imprecisos en la oración anterior. Es a propósito.

Es más, un patrón en general no tiene la intención de dictar cómo se debe diseñar el programa, sino que más bien, la idea es que, a medida que uno va diseñándolo, encontrará situaciones donde la solución comienza a asemejarse al patrón. Tal como hay ciertas guías para reorganizar código (refactorings), los patrones sirven como guías para reorganizar el diseño o arquitectura del sistema. Y tal como una lectura del tomo por Fowler nos deja la impresión de explica algo que es obvio, las descripciones sobre patrones de diseño tienden a sonar simplonas y autoevidentes.

Orden en el escritorio

Volviendo al tema de las aplicaciones que crecen forma orgánica. Yo pienso que la clave es ser equilibrado. El arquitecto, o el artista comienza con una idea general, probablemente nebulosa. A medida que dibuja el boceto, algunos conceptos comienzan a tomar formas definidas. Puede que los primeros intentos resulten defectivos, pero no importa, al cabo se trata de ideas generales. Luego viene el diseño detallado donde hay que tomar innumerables decisiones sobre la forma definitiva de lo que se está creando.

En software, no tiene sentido tratar de diseñar la aplicación completa sin escribir ni una sola línea de código. Pero tampoco es sensible empezar a escribir código sin siquiera tener una idea general de cual es la forma general y propósito del sistema. Entendiendo esos conceptos iniciales de lo que se quiere resolver con la aplicación es lo que permite decidir qué herramientas usar. Por ejemplo, no toda aplicación es candidata a ser desarrollada en Silverlight, o con ASP.NET, o hasta con Windows.

De igual manera, si resulta que Silverlight es la solución apropiada, no toda aplicación es apta a ser diseñada de la misma manera. Independientemente de su aspecto gráfico, las necesidades de un juego son comúnmente muy diferentes de las de un procesador del matrículas para una universidad.

Siendo aún un poco más atrevido, diré que la forma en que se diseña la aplicación tiene poca importancia si al final el producto trabaja apropiadamente. Pero hay ciertas condiciones. Por ejemplo, de seguro cada uno de nosotros tiene formas diferentes de organizar el escritorio. Para algunos, el escritorio debe estar limpio, y tener solamente lo que se está usando en ese momento. Papeles, libros y demás están todos organizados en archivadores y estantes. Para otros, el escritorio consta de torres de papeles y libros, junto con docenas de otros objetos apilados sin ton ni son aparente. En ambos casos, mientras la persona se sienta cómoda y sea productiva, el estado del escritorio es irrelevante.

Por supuesto, puede que algunos objeten sobre el desorden del segundo caso. Se ve feo. Es un completo desorden. No obstante, en muchos casos los habitantes de tales alborotos saben muy bien dónde está todo y lo pueden encontrar en un instante. Es más, todo está a la mano. Se puede argumentar que la persona con el escritorio ordenado tiene un mejor ambiente de trabajo. Es cierto, la apariencia es nítida y todo está en su lugar, pero cualquier cosa que tal persona necesite, requiere un viaje al archivador o al librero. De modo que las ventajas no son tan evidentes. Cada estilo tiene puntos buenos y malos. Mientras la persona esté cómoda en su propio escritorio, tales comparaciones son fútiles.

El lío se arma cuando viene alguien no familiarizado con el sistema. Un nuevo trabajador tendrá serios problemas encontrando algo en el escritorio similar a la zona de guerra. Hasta que no sea tan experto como el trabajador original, su productividad va a ser terrible. Por otra parte, un trabajador nuevo al que le toque el escritorio ordenado y clasificado tendrá menos dificultades en ser productivo. Eventualmente puede que en ambos escritorios los trabajadores sean igual de productivos, pero el tiempo que toma llegar a ese nivel es muy diferente en cada caso.

Es cuestión de equilibrio

Pasando la analogía al diseño de software, una aplicación en la que toda la lógica ocurre en el código subyacente de las ventanas o formularios de web, no es necesariamente mala. La funcionalidad está toda allí y no hay que navegar una docena de clases antes de encontrar quién diantres escribe los datos al archivo.  De igual manera, una aplicación organizada minuciosamente en componentes o capas no es necesariamente mejor. Cada capa o separación introduce más complejidad y afecta el rendimiento del sistema.

Sin embargo, si existe la posibilidad de que múltiples desarrolladores trabajen simultáneamente (o en diferentes épocas) en el sistema, hay ciertas ventajas en un sistema más organizado y separado en componentes con responsabilidades definidas. El tiempo que toma entender el sistema a grandes rasgos es menor. En fin,  la mantención del sistema es más simple.

De nuevo, el asunto es ser equilibrado. ¿Se trata de una aplicación personal? ¿O tal vez una aplicación utilitaria con un par de botones y dos o tres controles adicionales? En tales casos el trabajo de organizar la aplicación puede tener pocas ventajas.

Pero si hablamos de aplicaciones empresariales, o cuando existe la posibilidad de que otros tengan que mantener el sistema más adelante, o de que se tenga que alterar el sistema a medida que los requerimientos cambian, es buena idea considerar seriamente una organización más estricta para la aplicación.

Nótese que tal organización sería muy diferente de un caso a otro. Puede que la organización implique mejores comentarios, o el uso de regiones, o la creación de algunas clases auxiliares. O puede que implique subsistemas múltiples divididos a su vez en componentes y clases.

Silverlight y MVVM

Al final, llegamos al meollo del asunto. Al inicio teníamos aplicaciones en Windows. Luego surgió ASP y ASP.NET, ambos con diferentes modelos y entornos de trabajo que requieren una filosofía diferente al escribir aplicaciones. Todos los que han cruzado al mundo de aplicaciones de Web están familiarizados con el impacto que causa darse cuenta de que cada vez que el navegador envía una acción al servidor, éste ha olvidado completamente todo lo que habíamos creado hace apenas un segundo, y tiene que comenzar de nuevo desde cero.

De igual manera, Silverlight es lo suficientemente diferente de Windows Forms y ASP.NET como para requerir un reajuste en nuestra forma de crear aplicaciones. Los que han desarrollado en ambos entornos, tienen cierta ventaja, pero es todavía un reto. Más fácil es para los que han desarrollado en WPF, puesto que Silverlight es muy similar.

Desde un principio, los desarrolladores en WPF notaron que el patrón MVVM se adapta muy bien a ciertos tipos de aplicaciones en este entorno. Tal característica ha sido heredada por Silverlight. Es más, en Silverlight la separación entre el cliente y le servidor es intrínseca y concreta, en vez de ser simplemente un artefacto conceptual. La naturaleza física de la separación hace fácil el ver los datos como algo remoto, hasta cierto punto ajeno a la aplicación Silverlight en el cliente que tiene cierto sabor a presentador de tal información.

El problema perenne en tal situación es el pegamento o adaptador entre el mundo de los datos y el mundo visual de su representación. MVVM es un boceto, o estrategia para implementar tal intermediario. El propósito es crear sistemas en los que hay cierto número de componentes con responsabilidades claramente definidas.

¿Quiere decir que toda aplicación en Silverlight debería ser diseñada usando el patrón MVVM? NO. MVVM no es la única estrategia disponible. De hecho, es posible crear una aplicación al estilo tradicional, usando solamente código subyacente. Una vez más, depende del tipo de aplicación, su uso, y las circunstancias en las que se va a mantener.

Con todo y todo, MVVM ha tomado cierto impulso dentro de la comunidad de desarrolladores de Silverlight, y sea que uno esté de acuerdo o no, es bueno al menos saber de qué se trata.

Bueno entonces, ¿qué p(bip) es MVVM?

Aunque parezca mentira, nadie sabe con absoluta certeza la respuesta a esa pregunta. El problema es que MVVM es extremadamente ambiguo en su definición. Las siglas representan el nombre en inglés para Modelo, Vista y Modelo de Vista. Y la definición básica es que el modelo contiene los datos, la vista presenta esos datos al usuario, y el modelo de vista es lo que conecta a ambos.

Es fácil ver los problemas de tal concepto. De hecho, ¿exactamente qué significa que el modelo contenga los datos? ¿Qué hay de las reglas o lógica que manipula tales datos? ¿Está el modelo a cargo de la seguridad de la información mediante autenticar y autorizar su acceso? Y la vista, ¿tan sólo presenta los datos, o también se encarga de responder a acciones del usuario? ¿Puede la vista hacer pequeños cambios a la información, o tiene que enviar cada solicitud de cambio al modelo?

Y en todo esto, ¿qué es el modelo de vista, y por qué es necesario? ¿Por qué no puede la vista simplemente conectarse al modelo sin usar un intermediario? Y si al final se nos convence de que se ocupa el modelo de vista, ¿exactamente qué es lo que hace? ¿Cómo puedo adaptarlo a mi diseño?

Esas y otras muchas preguntas son comunes y las respuestas aún están tomando forma. Nadie tiene todavía una idea completa del asunto. De hecho puesto que es tan sólo un patrón de diseño, la forma específica que tome su implementación cambiará de aplicación a aplicación.

Por experiencia propia, yo sugiero:

  • Investigar y obtener un concepto general del tema
  • Estudiar tantos ejemplos como sea posible
  • Tratar de diseñar una aplicación relativamente pequeña  usando el patrón

Para el primer ítem, he publicado un artículo escrito originalmente en inglés por Jeremy Likness explicando en detalle el MVVM y presentando algunos casos comunes donde uno puede encontrar dificultades. También ofrece comentarios sobre varias bibliotecas que ayudan a implementarlo. Hace algún tiempo empecé a escribir un artículo con una idea similar, pero Jeremy hizo un trabajo mucho mejor.

Habiendo estudiado el patrón, fastidiado a varios miembros de la comunidad con montones de preguntas, y caminado paso a paso por docenas  de ejemplos, hace poco tuve la oportunidad de ejecutar el tercer paso y crear una aplicación pequeña pero lo suficientemente compleja como para justificar el uso del patrón (ok, ok, tal vez no tan justificadamente). El proceso fue interesante y lleno de lecciones. Mi plan es dar cuenta de algunos los puntos principales en futuros artículos que puedan servir de ayuda a los que van por el mismo camino.

Categories: General Tags: , ,

Enlace a datos, almacenaje local, MVVM y MEF

April 4th, 2010 2 comments

En las últimas semanas he agregado algunos artículos nuevos.

La serie de Tim Heuer introduce el desarrollo de aplicaciones en Silverlight y parece ser muy popular. Ahora está disponible la cuarta parte que cubre uno de los aspectos más poderosos de Silverlight: enlace a datos (o databinding en inglés). Si bien el mecanismo en sí ha existido por largo tiempo en .NET, tanto en WPF como en Silverlight toma un papel mucho más prominente en el diseño de la aplicación. Se puede decir que entender bien el modelo de enlace a datos es fundamental en Silverlight. Luego, hacia el final del artículo, Tim cubre un poco sobre el uso de almacenaje de datos en el cliente. El almacenaje local permite guardar preferencias y otra información relevante de manera fácil y segura.

Un tema más avanzado es el diseño de aplicaciones usando el patrón MVVM. Aunque todavía genera gran controversia en la comunidad, especialmente con respecto a qué exactamente es la parte VM (ViewModel o modelo de vista), no hay duda de que es digno de ponerle atención. Al cabo es un patrón y no una receta, por lo que se presta a que cada desarrollador lo interprete a su manera. Con todo y todo, comienzan ya a surgir programas que han aplicado MVVM exitosamente en su diseño. En la segunda parte de su serie, Shawn Wildermuth sugiere cómo usar MEF como herramienta de implementación del patrón MVVM. Shawn tiende a ser muy práctico, dando cuenta no sólo del concepto en general, sino que también narrando las dificultades que ha encontrado y sus posibles soluciones.

Es todo por ahora. Sigo mientras tanto, trabajando en otros artículos. Sus sugerencias y preguntas son siempre bienvenidas.

David

Patrones de diseño para Silverlight

March 10th, 2010 No comments

Silverlight se ha ido solidificando gradualmente como plataforma viable de desarrollo. Igualmente las aplicaciones han pasando de ser mayormente demostraciones de habilidades gráficas y audiovisuales a sistemas más complejos y de mayor escala. Y con ese crecimiento, ha surgido la necesidad de encontrar patrones o guías de diseño que se adapten bien a la particular combinación de componentes, recursos, limitaciones y circunstancias típicas de una aplicación de este tipo.

Unos de los patrones más discutidos es el Model-View-ViewModel (MVVM por sus siglas en inglés). Por cierto que es una de esas frases que resulta compacta y comunicativa en inglés, pero para la que no hay un equivalente en español con las mismas cualidades. Luego de consultar con otros autores de este sitio y darle algunas vueltas terminé con el nombre: Modelo-Vista-Vista de Modelo. De todos modos, se aceptan sugerencias.

Pero volviendo al MVVM, es parte de la serie de patrones como MVC y MVP, donde se tiene un modelo con los datos y las reglas que los manipulan, una vista que da la representación visual de la información, y un “algo” un tanto nebuloso que sirve de intermediario. En parte por la perenne confusión que existe al respecto, estoy trabajando en un artículo original (en vez de algo que haya traducido) considerando los diferentes patrones y sus relaciones y diferencias. Estoy seguro que un artículo más sobre el tema será de gran ayuda para aumentar la confusión generalizada. Eh, digo…

En todo caso, con el fin de ayudar a los que se ven ya en necesidad de adoptar un enfoque más disciplinado en su diseño de aplicaciones en Silverlight, especialmente en un ámbito empresarial, o donde hay manejo de datos a gran escala, he estado buscando artículos que cubran el tema. Por el momento estoy trabajando con Shawn Wildermuth y Jeremy Likness, ambos excelentes autores y asesores en Silverlight, WCF RIA, en prácticas de ingeniería y diseño de software.

Su estilo de presentación varía un poco, pues más que guías de paso a paso, son explicaciones que presentan una aplicación y dan las razones para las decisiones tomadas al implementarla. En general, estos artículos son un poco más avanzados y asumen cierta familiaridad con Silverlight, su entorno de desarrollo, y los aspectos fundamentales de arquitectura de software. Aún así el material es excelente y es bueno que hasta los principiantes empiecen a estudiarlos desde un principio.

El primero en salir es la parte introductoria de una serie de cuatro artículos sobre el diseño de sistemas en Silverlight 4 usando MVVM, MEF, y los Servicios RIA. En esta parte, Shawn explica por qué ciertas estrategias tradicionales para el uso de fuentes de datos no son muy apropiadas en Silverlight. También da un vistazo al patrón MVVM con una aplicación de ejemplo que se usará durante toda la serie.

Diseño de aplicaciones en Silverlight 4 usando Servicios RIA, MEF y MVVM – Parte 1

Espero que les sea de ayuda. Las siguientes partes ya vienen en camino.