Blog de Fernando Machado Piriz

Artículos sobre transformación digital, arquitectura empresarial y temas relacionados

Resultados de la búsqueda

Una introducción simple al patrón Model View ViewModel para construir aplicaciones Silverlight y Windows Presentation Foundation

with 12 comments

Hace algún tiempo estuve buscando una introducción simple al patrón Model View ViewModel (también conocido como MVVM) y todos los ejemplos que encontré eran un poco complicados para mi gusto. En este artículo trataré de presentarles el patrón MVVM usando el ejemplo más simple posible, enfocándome solo en los conceptos clave de MVVM. En otros artículos entraré en detalle de conceptos relacionados, pero vamos a comenzar con lo básico.

MVVM es un sucesor de otro patrón bien conocido y exitoso como es el Model View Controller (MVC). MVC nació (como tantos otros patrones bien conocidos y exitosos) en el mundo de Smalltalk hace más de treinta años. Al usar MVC la aplicación se compone de tres tipos de objetos, con responsabilidades bien claras y diferenciadas:

  • El modelo. Habitualmente hay un solo modelo por aplicación. El modelo es responsable de todos los datos de la aplicación y de la lógica de negocios relacionada.
  • La vista o vistas. Una o más representaciones para el usuario final del modelo de la aplicación. La vista es responsable de mostrar los datos al usuario y de permitir la manipulación de los datos de la aplicación.
  • El controlador o controladores. Habitualmente hay un controlador por vista, aunque no es raro ver un controlador por entidad de dominio controlando varias vistas. El controlador es responsable de transferir datos desde el modelo hacia la vista asociada y viceversa. También es responsable de implementar el comportamiento de la vista para responder a las acciones de los usuarios.

image

Con MVC cada tipo de objeto es responsable de solo una cosa, lo que simplifica el desarrollo, comprensión y prueba del código. Además, es fácil reemplazar las vistas, o tener más de una vista de los mismos datos.

En el caso de las aplicaciones Silverlight o Windows Presentation Foundation (WPF/SL), el .NET Framework provee la capacidad de usar bindings para transferir datos desde y hacia la vista, por lo que el controlador solo es responsable de implementar el comportamiento de la vista. En este caso, el controlador es llamado modelo-vista (view model), dando origen al patrón MVVM:

  • El modelo. Lo mismo que en MVC.
  • La vista o vistas. Igual que en MVC.
  • El modelo-vista. Uno o más por vista. El modelo-vista es responsable de implementar el comportamiento de la vista para responder a las acciones del usuario y de exponer los datos del modelo de forma tal que sea fácil usar bindings en la vista.

image

MVVM comparte todos los beneficios de MVC, pero tiene un beneficio adicional: la simplificación que resulta de usar binding declarativo para transferir los datos desde y hacia el modelo a la vista.

Voy a mostrar cómo funciona MVVM con un ejemplo. El código que voy a estar usando es de mi aplicación de ejemplo Giving a Presentation (aunque los animo a descargar el archivo de instalación y el código fuente de CodePlex, no hay necesidad de hacerlo para entender este artículo).

Giving a Presentation es una simple aplicación para cambiar ciertas configuraciones del equipo mientras damos una presentación, por ejemplo, ocultar los íconos del escritorio, remover o reemplazar el fondo del escritorio, etc. Los cambios son deshechos cuando la presentación termina.

La capacidad para cambiar estas configuraciones es provista por partes extensibles y no está implementada en la propia aplicación (más detalles en este artículo). Por lo tanto, siendo estrictos, los datos que maneja Giving a Presentation son solo un valor lógico que indica si el usuario está dando una presentación o no: el usuario asigna el valor en verdadero cuando comienza la presentación y lo vuelve a falso cuando la presentación termina.

El código del modelo aparece a continuación. Como prometí, es muy simple; sólo tiene una propiedad lógica:

public class Model
{
    public bool GivingAPresentation { get; set; }
}

He aquí el código del modelo-vista. También es muy simple. Como el modelo, sólo tiene una propiedad lógica, cuyo valor se obtiene de una instancia del modelo:

public class MainViewModel
{
    private Model model;
    public bool GivingAPresentation
    {
        get { return model.GivingAPresentation; }
        set
        {
            model.GivingAPresentation = value;
        }
    }

    public MainViewModel()
    {
        this.model = new Model();
    }
}

La vista (sin ninguna extensión) luce así:

clip_image006

El código XAML correspondiente es:

<Window x:Class="GivingAPresentation.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:GivingAPresentation "
        Title="Giving a Presentation" Height="350" Width="525" Icon="/MvvmDemo;component/Images/Presentation.ico">
    <Window.Resources>
        <vm:MainViewModel x:Key="mainViewModel"/>
    </Window.Resources>
    <Grid>
        <CheckBox Content="I'm currently giving a presentation"
                  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="12,12,0,0"
                  IsChecked="{Binding Source={StaticResource mainViewModel}, Mode=TwoWay, Path=GivingAPresentation}" />
    </Grid>
</Window>

Es interesante mencionar que no hay code-behind para esta vista [1] (es más, he borrado el archivo MainView.xml.cs del proyecto, y obviamente la solución compila y la aplicación ejecuta perfectamente). ¿Se preguntan por qué? Porque no hay necesidad de ningún código en el code-behind de la clase; el comportamiento de la vista está programado en el modelo-vista, no en la vista, ¿recuerdan?

La vista está conectada con el modelo en tres pasos. Primero, un atributo xmlns en el nodo Window es usado para crear un alias vm al espacio de nombres GivingAPresentation con xmlns:vm=”clr-namespace:GivingAPresentation. Luego, una instancia del modelo-vista es creada en el nodo Window.Resources; el nombre de esta instancia es declarado con x:Key=”mainViewModel”. Finalmente la propiedad IsChecked de la casilla de verificación de la vista es bindeada con la propiedad GivingAPresentation del modelo-vista con IsChecked=”{Binding Source={StaticResource mainViewModel}, Mode=TwoWay, Path=GivingAPresentation}”.

Y eso es todo. WPF/SL hacen la magia de obtener el estado de la casilla de verificación del valor de la propiedad del modelo-vista, quién a su vez lo obtiene de la propiedad correspondiente del modelo. A través de esta cadena, un cambio en la vista se refleja en el modelo y viceversa.

Este ejemplo es tal vez demasiado simple, pero tiene todos los componentes del patrón MVVM, y muestra claramente los fundamentos para implementar aplicaciones WPF/SL usando ese patrón.

¿Qué sigue? Hay varias cosas, muy comunes en escenarios de aplicaciones del mundo real, que no están resueltas en absoluto en este ejemplo tan simple; por ejemplo:

  1. No sólo la vista, sino probablemente otros objetos, necesiten estar al tanto de los cambios en las propiedades del modelo-vista. Aquí es donde entra en juego la interfaz INotifyPropertyChanged. Al disparar un evento PropertyChanged cada vez que cambia el valor de una propiedad, otros objetos pueden reaccionar a esos cambios. Vale la pena mencionar que estos otros objetos no son conocidos por el modelo-vista, pero son notificados de todas formas, gracias a la infraestructura de eventos del .NET Framework.
  2. Es muy común que la vista pida al modelo-vista que ejecute ciertas acciones. Esto se puede lograr si el modelo-vista expone comandos, y la vista usa bindings para ciertas acciones (como el clic de un botón) a esos comandos.
  3. También es muy común que las aplicaciones de la vida real tengan varias vistas interdependientes que necesitan comunicarse entre ellas. Para mantener estas vistas, y sus modelos-vista asociados, independientes unos de otros, los modelos-vista pueden usar mensajes para comunicarse entre ellos.
  4. ¿Quién crea a quién? En este ejemplo la vista crea declarativamente el modelo-vista (en el código XAML de la vista), y el modelo-vista crea el modelo. En aplicaciones más grandes, este enfoque no siempre es adecuado, y son necesarias otras clases para manejar la creación de objetos.

Estos aspectos no son realmente parte del patrón MVVM, pero son realmente necesarios para implementar aplicaciones del mundo real usando WPF/SL; es por es que pueden verlos junto con el patrón MVVM en la literatura. Planeo cubrir estos temas en futuros artículos y no en este, para mantener esta simple introducción, simple.

Espero hayan disfrutado de la explicación. Espero verlos pronto. Adiós.


[1] En este ejemplo. En el código real de Giving a Presentation, el vista es responsable de tareas relacionadas con la presentación, como mostrar el ícono de notificación cuando se minimiza por ejemplo, que require code-behind en la vista.

Written by fernandomachadopiriz

09/06/2010 at 23:03

El nuevo Visualization and Modeling Feature Pack permite generar diagramas UML a partir del código y viceversa

leave a comment »

Microsoft publicó reciente el Visualization and Modeling Feature Pack para Visual Studio 2010. La descarga está disponible para suscriptores de MSDN aquí. Incluye las (largamente esperadas) características siguientes:

  • Generación de código a partir de diagramas UML.
  • Generación de diagramas UML desde el código.
  • Importar elementos de modelos de clase, secuencia, y casos de uso UML desde archivos XMI 2.1.
  • Crear y ver vínculos desde work items a elementos de los modelos.
  • Generar grafos de dependencias desde proyectos web ASP .NET, C y C++.
  • Crear y validar diagramas de capas para código C y C++.
  • Escribir código personalizado para crear, modificar y validar diagramas de capas.

El siguiente diagrama de clases UML de Giving a Presentation fue creado usando el Visualization and Modeling Feature Pack en cuestión de un par de minutos:

ClassDiagram

¿Reconocen cómo fue usado el patrón Model View View Model? Es fácil a partir del diagrama, ¿no?

Written by fernandomachadopiriz

16/06/2010 at 18:25

Una nueva vida para un viejo blog

leave a comment »

Este blog nació hace más de cuatro años. En aquél tiempo trabajaba como Arquitecto de Soluciones independiente y como docente de los cursos Programación e Ingeniería de Software en la Universidad Católica del Uruguay. Había sido designado por Microsoft como Most Valuable Professional desde 2008 hasta 2010 cuando comencé a trabajar como Consultor de Desarrollo en Microsoft.

En aquél tiempo escribía sobre los temas que sabía o aprendía y que creía que a los lectores les podían interesar: programación —C#, .NET Framework, Visual Studio—, gestión del ciclo de vida del software —Team Foundation Server—, nuevas tecnologías —LightSwitch—, y trataba de explicar conceptos difíciles en forma fácil —Covarianza & Contravarianza, Inversion of Control & Dependency Injection, Model View ViewModel-.

Luego por el trabajo que hacía y los temás que desarrollaba dejé de escribir. Ahora hace más de dos años que trabajo como Arquitecto Empresarial en Microsoft y estoy comenzando nuevos cursos de Arquitectura en el grado y en la maestría de la Universidad Católica del Uruguay.

Entonces quiero comienzar a escribir nuevamente pero, en temas de arquitectura, que podrán comenzar a leer en breve. Espero poder escribir artículos tan interesantes como antes, más allá que sean otros temas.

No puedo afirmar si el blog fue exitoso o no hasta ahora, aunque algunos números pueden dar una idea: entre los artículos en español y en inglés más los videos de demos correspondientes en YouTube, hay más de 260.000 visitas en poco más de 4 años y desde los más diversos lugares del mundo:

image

Visitas por mes al blog en español

image

Visitas por país al blog en español

Espero que los viejos lectores todavía quieran acompañarme y espero nuevos lectores también. Hasta la próxima.

Written by fernandomachadopiriz

20/07/2014 at 08:52

Publicado en Anuncios