Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado _ Maromas Digitales.pdf
Transcript of Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado _ Maromas Digitales.pdf
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 1/28
Portada
Artículos Por Autor
Acerca
Contactar
Buscar Buscar
Usando MEF en vez de PRISM en Silverlight – Parte 2 de 2: Administración de Regiones Lanzamiento de Expression Studio 4:
Blend, Web, Encoder, Design
Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado
Publicado el 28 de Mayo, 2010, en Silverlight, por David Mora
Traducción aproximada del artículo Model-View-ViewModel (MVVM) Explained publicado en inglés por Jeremy Likness el
14 de abril del 2010 en su blog C#er:Image.
El propósito de este artículo es dar una introducción al patrón Modelo-Vista-Modelo de Vista (Model-View-ViewModel en
inglés y abreviado como MVVM). Aunque he participado en numerosas discusiones en línea sobre el tema, me parece que
los que están principiando encuentran poco material disponible y tienen que vadear entre múltiples recursos
contradictorios antes de poder usar el patrón en su código. Mi idea no es declarar dogmas, sino más bien agrupar varios
conceptos en solo artículo con el fin hacer más fácil la tarea de entender y apreciar el valor de dicho patrón. MVVM es
mucho más simple de lo algunos lo hacen parecer.
¿Por qué debería interesarme el MVVM?
¿Qué razón hay, como desarrolladores, para siquiera poner atención al Modelo-Vista-Modelo de Vista? El patrón aporta
varios beneficios tanto a WPF como a Silverlight. Antes de continuar, vale preguntarse:
¿Necesito compartir mi proyecto con un diseñador y tener la flexibilidad de que ambos aspectos de diseño y
desarrollo se lleven a cabo casi simultáneamente?
¿Requiero pruebas unitarias comprensivas para mis soluciones?
¿Es importante para mí el tener componentes reutilizables tanto dentro de un proyecto como a través de mi
organización?
¿Desearía yo tener mayor flexibilidad para poder cambiar la interfase al usuario en una aplicación sin tener que
reorganizar su lógica?
Una respuesta afirmativa a cualquiera de estas preguntas indica que es buena idea investigar el MVVM. Estos son sólo
algunos de los beneficios que puede otorgarle a sus proyectos.
Me asombran algunos de los diálogos que a veces encuentro en la red. Argumentos como “MVVM sólo tiene sentido en
interfaces gráficas extremadamente complejas” o “MVVM conlleva demasiado esfuerzo y es excesivo para aplicaciones
pequeñas.” El colmo es escuchar que “MVVM no es adaptable.” En mi opinión, declaraciones como éstas se refieren a ideas
preconcebidas o implementaciones específicas de MVVM y no al patrón en sí. Dicho de otra forma, si toma horas
ensamblar una aplicación usando MVVM, entonces algo no se está haciendo bien. Si la aplicación no es flexible, la culpa no
es del modelo, sino de la forma en la que se le usa. Por ejemplo, sin importar el patrón usado, sería ridículo tratar de
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 2/28
enlazar 100 000 artículos a un control ListBox.
Así que, antes de continuar, una pequeña aclaración: en vez de presentarlo como una verdad absoluta, lo que voy a hacer es
explicar la forma en la que yo veo MVVM. Los animo a que compartan sus puntos de vista y experiencias en área de
comentarios. Si les parece que algo no es correcto, déjenmelo saber y trataré de mantener este artículo actualizado.
MVVM a grandes rasgos
Examinemos las partes principales de MVVM, empezando con un fundamento esencial para toda aplicación: los datos.
Estos son contenidos en el modelo.
El Modelo
El modelo representa los datos o información con la que trabajamos y por eso me gusta llamarlo
el objeto del dominio. Un ejemplo de modelo puede ser un contacto (con su nombre, número de
teléfono, dirección y demás) o la descripción de un punto de publicación para un medio
audiovisual transmitido en vivo.
La clave para recordar el modelo es que contiene la información, pero no las acciones o servicios
que la manipulan. No es responsable de darle forma para que se vea bien en la pantalla, o de
obtener una lista de elementos de un servidor remoto (de hecho, en tal lista cada elemento sería
a su vez un modelo). La lógica de la aplicación o “reglas empresariales” son generalmente
mantenidas en clases separadas del modelo y actúan en él. Aunque no siempre es cierto, a veces
el modelo puede validar la información.
No es fácil mantener el modelo nítido, especialmente al representar entidades del mundo real.
Por ejemplo, el registro de un contacto puede que incluya la fecha en que fue modificado por
última vez junto con la identidad de quien hizo la modificación (para efectos de auditoría), demás de identificador único
(usado en la base de datos o similar). La fecha de modificación no tiene ninguna conexión con el contacto en la vida real,
pero es un efecto secundario asociado con la forma en la utilizamos, le damos seguimiento, y la almacenamos en el
sistema.
Veamos, por ejemplo,un posible modelo para mantener información sobre un contacto:
namespace MVVMExample
{
public class ContactModel : INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 3/28
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
public string FullName
{
get { return string.Format("{0} {1}",
FirstName,
LastName); }
}
private string _phoneNumber;
public string PhoneNumber
{
get { return _phoneNumber; }
set
{
_phoneNumber = value;
RaisePropertyChanged("PhoneNumber");
}
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this,
new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public override bool Equals(object obj)
{
return obj is ContactModel &&
((ContactModel) obj).FullName.Equals(FullName);
}
public override int GetHashCode()
{
return FullName.GetHashCode();
}
}
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 4/28
}
La Vista
La vista es la parte con la que estamos más familiarizados y la que ve el
usuario. Su papel es representar la información, tomándose a veces ciertas
libertades con el fin de hacerla más clara o presentable. Por ejemplo, una
fecha podría ser representada en el modelo como el número de segundos
contados desde la medianoche del primero de enero de 1970 (Tiempo
Unix). Sin embargo, el número es presentado al usuario en forma de día, mes
y año en su zona horaria local. Una vista puede también contener ciertos
comportamientos, como el aceptar la entrada de datos. La vista se encarga
de esta faceta (teclas presionadas, movimientos del ratón, gestos en una
pantalla táctil, y así por el estilo) que eventualmente ejerce influencia en las
propiedades del modelo.
En MVVM la vista es activa. A diferencia de una vista pasiva sin conocimiento del modelo, y bajo el manejo total de un
controlador o presentador, la vista en MVVM contiene comportamientos, eventos y enlaces a datos que, hasta cierto punto,
necesitan saber sobre el modelo subyacente y el modelo de vista. Aunque tales eventos y comportamientos son asociados
a propiedades, métodos y comandos, la vista es aún responsable de manejar sus propios eventos y no pasa esta tarea al
modelo de vista.
Algo digno de recordar sobre la vista es que no es responsable de llevar cuenta de su estado. El modelo de vista se
encarga de ello y mantiene la vista al tanto de los cambios.
La siguiente es una vista de muestra expresada en XAML:
<UserControl x:Class="MVVMExample.DetailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot"
Background="White"
DataContext="{Binding CurrentContact}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Name:"
HorizontalAlignment="Right"
Margin="5"/>
<TextBlock Text="{Binding FullName}"
HorizontalAlignment="Left"
Margin="5"
Grid.Column="1"/>
<TextBlock Text="Phone:"
HorizontalAlignment="Right"
Margin="5"
Grid.Row="1"/>
<TextBlock Text="{Binding PhoneNumber}"
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 5/28
HorizontalAlignment="Left"
Margin="5"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
</UserControl>
Noten que los diferentes enlaces son los puntos de integración o sincronización con el modelo de vista.
El modelo de vista (Nuestro controlador o presentador)
El modelo de vista introduce el concepto de Separación de la Presentación, es decir,
mantiene al modelo separado y protegido de los minuciosos detalles de la vista. Por
eso es que el modelo de vista es la pieza clave del trío. Esta separación permite que
el modelo se limite a contener los datos, en vez de verse obligado a saber la forma
en que se presenta una fecha al usuario y tener que hacer la conversión de formato.
De igual manera, la vista sólo tiene que presentar la fecha. El controlador trabaja
como intermediario entre ambos, recibiendo información de la vista e insertándola
en el modelo, o actuando con un servidor para obtener datos del modelo y luego
convertirlos en propiedades que pueden ser usadas en la vista.
El modelo de vista también hace disponibles métodos, comandos y otros puntos de acceso que ayudan a mantener el
estado de la vista, manipular el modelo en respuesta a acciones de la vista y disparar eventos en la misma.
Si bien ya había estado evolucionando entre bastidores por bastante tiempo, John Gossman introdujo el MVVM al público
en general en un artículo de su blog de Microsoft en el 2005 tratando sobre Avalon (el sobrenombre para Windows
Presentation Foundation, o WPF). El artículo, titulado Introduction to Model/View/ViewModel pattern for building WPF
Apps generó un gran revuelo a juzgar por los comentarios de los que trataban de comprenderlo.
En ocasiones he escuchado al MVVM descrito como una implementación del Patrón de Modelo de Presentación diseñada
específicamente para QPF (y posteriormente Silverlight).
Los ejemplos del patrón generalmente enfatizan el uso de XAML para definir la vista y enlaces de datos para los comandos
y propiedades. Tales detalles no son intrínsecos del patrón sino más bien detalles de su implementación. Por eso es que
señalo el enlace a datos con un color diferente:
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 6/28
Abajo presento un ejemplo de un posible modelo de vista donde hemos creado una clase BaseINPC (siglas en inglés para
“INotifyPropertyChanged”) proveyendo un método que facilita generar el evento de notificación cuando se altera alguna de
las propiedades.
namespace MVVMExample
{
public class ContactViewModel : BaseINPC
{
public ContactViewModel()
{
Contacts = new ObservableCollection<ContactModel>();
Service = new Service();
Service.GetContacts(_PopulateContacts);
Delete = new DeleteCommand(
Service,
()=>CanDelete,
contact =>
{
CurrentContact = null;
Service.GetContacts(_PopulateContacts);
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 7/28
});
}
private void _PopulateContacts(
IEnumerable>ContactModel> contacts)
{
Contacts.Clear();
foreach(var contact in contacts)
{
Contacts.Add(contact);
}
}
public IService Service { get; set; }
public bool CanDelete
{
get { return _currentContact != null; }
}
public ObservableCollection<ContactModel> Contacts
{ get; set; }
public DeleteCommand Delete { get; set; }
private ContactModel _currentContact;
public ContactModel CurrentContact
{
get { return _currentContact; }
set
{
_currentContact = value;
RaisePropertyChanged("CurrentContact");
RaisePropertyChanged("CanDelete");
Delete.RaiseCanExecuteChanged();
}
}
}
}
Como se puede notar, este modelo de vista fue diseñado para administrar una lista de contactos, incorporando un
comando para eliminarlos y una señal indicando se se permite borrar datos (por lo tanto, manteniendo el estado de la
vista). Generalmente la bandera sería parte del comando, pero este ejemplo está basado en Silverlight 3 que no es
compatible con el enlace de comandos, y yo quise demostrar una solución simple sin recurrir a una infraestructura excesiva.
(Les recomiendo ver este vídeo que demuestra lo fácil que es convertir el ejemplo de Silverlight 3 a 4 y usar el sistema
nativo de comandos). El modelo de vista en el listado anterior hace una referencia concreta al servicio.
Para aplicaciones de mayor escala prefiero conectar la referencia de manera externa o usando una infraestructura de
inyección de dependencias. Lo chévere es la flexibilidad de construirlo de esta manera inicialmente y luego reorganizarlo
según se necesite—de nuevo, como se puede ver en el ejemplo, no es estrictamente necesario usar una infraestructura o
biblioteca externa para implementar el patrón. En nuestro caso, el modelo de vista va y obtiene la lista de contactos
inmediatamente. Por el momento es una lista predeterminada con mis detalles y los de alguien un poco más conocido. Por
si acaso, los números de teléfono son falsos.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 8/28
Seamos un poco más específicos y veamos como podríamos implementar esto en una aplicación de muestra. Una vista de
rayos X de su configuración en MVVM se vería así:
¿Qué podemos discernir de este vistazo?
Primero, IConfig representa un servicio de configuración (en un lector de mensajes de la red podría contener información
sobre la cuenta y los suministros que son obtenidos), mientras que IService es un servicio específico, tal vez la interfase que
trae los suministros de las fuentes RSS al lector.
La vista y el modelo de vista
La vista y el modelo de vista se comunican mediante enlaces de datos, métodos, propiedades, eventos y mensajes
El modelo de vista expone propiedades (tal como información sobre el estado de la vista, p.ej. el indicador de
“ocupado”) y comandos además de modelos
La vista se encarga de sus propios eventos relacionados con la interfase al usuario y los pasa al modelo de vista
mediante comandos
Los modelos y propiedades en el modelo de vista son actualizados desde la vista usando enlaces de datos
bidireccionales
Hay dos mecanismos que son frecuentemente usados en la implementación del patrón, gatillos o disparadores
(especialmente los relacionados con datos) en WPF, y el Controlador de Estados Visuales (Visual State Manager o VSM) en
Silverlight. Ambos ayudan por medio de unir los comportamientos de la interfase al usuario con los modelos subyacentes.
El VSM debería ser la opción principal para coordinar transiciones y animaciones en Silverlight. Más información sobre VSM
aquí.
El modelo de vista y el modelo
El modelo de vista es completamente responsable del modelo en este escenario.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 9/28
Por dicha no está solo:
El modelo de vista puede que exponga el modelo directamente o mediante propiedades relacionadas para uso en
enlaces de datos
El modelo de vista puede contener interfases a servicios, datos de configuración y similares, con el fin de obtener y
manipular las propiedades que ofrece
¿La gallina o el huevo?
Es posible que hayan escuchado controversias sobre quién lleva la delantera, la vista o el modelo de vista. A mí me parece
que la mayoría de desarrolladores estarían de acuerdo con que cada vista ha de tener solamente un modelo de vista. No
hay necesidad de asociarla con múltiples modelos de vista. Con esta separación de responsabilidades en mente, tiene
sentido que si uno tiene un control para contactos enlazado a un modelo de vista para contactos, y un control con
información sobre la compañía atado a un modelo de vista que provee esta información, ambos controles son vistas
separadas en vez de una sola con dos modelos de vista.
Una vista puede contener otras vistas, cada una con sus propio modelo de vista. Los modelos de vista pueden contener
otros modelos de vista cuando sea necesario (no obstante, es común ver a algunos consolidando sus modelos de vista
cuando en realidad lo que necesitan es un modo de comunicaciones entre ellos).
Una vista debe tener un único modelo de vista, pero este último puede ser usado por varias vistas (por ejemplo imaginen
un asistente (Wizard) con tres vistas pero un sólo modelo de vista que controla el proceso).
La vista como elemento principal
En este enfoque la vista es la que se encarga de crear o importar el modelo de vista. Generalmente usa el modelo de vista
como un recurso al que se enlaza ya sea explícitamente, mediante el patrón de localización, o mediante inserción usando
MEF, Unity o algo parecido. Es común usar esta técnica en el manejo de vistas y sus modelos de vista. Yo he publicado
algunos artículos sobre el tema:
ViewModel Binding with MEF
MVVM Composition in Silverlight with Prism
Prism, MEF, and MVVM
El ejemplo incluido con este artículo usa este método. La vista es creada y luego el modelo de vista es asociado. En el
objeto Application se ve de esta manera:
private void Application_Startup(object sender,
StartupEventArgs e)
{
var shell = new MainPage();
shell.LayoutRoot.DataContext = new ContactViewModel();
RootVisual = shell;
}
He mantenido el ejemplo sencillo mediante evitar el uso de infraestructuras auxiliares que ensamblen las interfases y sus
implementaciones.
El modelo de vista como elemento principal
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 10/28
Otra forma de conectar los componentes es mediante hacer al modelo de vista responsable de la creación de la vista y los
enlaces necesarios. Para un ejemplo de esta técnica pueden ver la presentación de Rob Eisenberg en MIX, Build your own
MVVM Framework, en la que crea una infraestructura basada en convenciones de uso.
La moraleja es que hay más de una manera de matarle las pulgas al perro.
Una infraestructura básica para MVVM
En mi opinión, una infraestructura para MVVM básica requiere sólo dos cosas:
1. Una clase basada en DependencyObject o que implemente INotifyPropertyChanged de manera que sea utilizable en
el enlace de datos, y
2. Algún tipo de mecanismo para comandos
Silverlight 3 cumple hasta cierto grado con el segundo requisito al proveer la interfase ICommand. Sin embargo, ahora en
Silverlight 4 tenemos algo más completo: los comandos permiten enlazar eventos en la vista al modelo de vista. Es un
detalle de implementación, pero facilita el uso del patrón MVVM.
Recuerden que Blend provee un surtido juego de herramientas para enlaces de datos y uso de comportamientos en su kit
de desarrollo. Pueden ver mi vídeo, MVVM with MEF in Silverlight, para obtener una idea de lo fácil que es implementar el
patrón MVVM aún sin el uso de una infraestructura auxiliar. El artículo Usando MEF en vez de PRISM demuestra cómo
pueden crear sus propios comandos.
En el ejemplo he creado una clase base que se encarga de los eventos generados por cambios en propiedades:
namespace MVVMExample
{
public abstract class BaseINPC : INotifyPropertyChanged
{
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this,
new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
También he implementado un comando. En la mayoría de los casos uno usaría un tipo más general de comando que sea
útil en situaciones variadas, pero con el fin de mantenerlo simple, el comando demostrado abajo se limita a la función de
borrado. En mi caso estoy usando un cuadro de diálogo para confirmar la eliminación. En caso de necesitar algo más
elegante, como un ventana de tipo ChildWindow, pueden leer los escenarios que describo más adelante para entender
mejor cómo incorporar el cuadro de diálogo como un servicio dentro del patrón MVVM.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 11/28
namespace MVVMExample
{
public class DeleteCommand : ICommand
{
private readonly IService _service;
private readonly Func<bool> _canExecute;
private readonly Action<ContactModel> _deleted;
public DeleteCommand(IService service,
Func<bool> canExecute,
Action<ContactModel> deleted)
{
_service = service;
_canExecute = canExecute;
_deleted = deleted;
}
public bool CanExecute(object parameter)
{
return _canExecute();
}
public void Execute(object parameter)
{
if (CanExecute(parameter))
{
var contact = parameter as ContactModel;
if (contact != null)
{
var result = MessageBox.Show(
"Are you sure you wish to delete the contact?",
"Confirm Delete",
MessageBoxButton.OKCancel);
if (result.Equals(MessageBoxResult.OK))
{
_service.DeleteContact(contact);
if (_deleted != null)
{
_deleted(contact);
}
}
}
}
}
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 12/28
public event EventHandler CanExecuteChanged;
}
}
Este comando en particular usa un delegado al que llama cuando ha terminado su trabajo, limitándolo a un único
suscriptor para el evento. Un delegado o evento múltiple es necesario si que quiere que varios modelos se puedan suscribir.
En Silverlight 4 es posible simplemente enlazar un botón al comando usando el atributo Command. El ejemplo arriba está
escrito en Silverlight 3 que no provee tal facilidad. Para crear el enlace usé un disparador (como antes, específico a este
proyecto y con el fin de simplificarlo) para invocar el comando, de manera que sea fácil enlazarlo al XAML.
Los ejemplos mostrados acá son parte de la aplicación adjunta al artículo. Tal aplicación es simple y contiene un único
servicio y un modelo de vista con una base de datos simulada. Dos vistas se enlazan al mismo modelo de vista de manera
que se puede hacer clic en un contacto para ver sus detalles. También es posible borrar contactos.
Recibo comentarios con cierta frecuencia diciendo que los ejemplos en el blog son muy simplistas. Este es lo
suficientemente complejo como para demostrar una aplicación completa sin depender en infraestructuras adicionales,
pero no muestra páginas y tipos de vista múltiples. La razón es simple: siendo un asesor y desarrollador independiente,
constantemente estoy escribiendo estas aplicaciones y bibliotecas para clientes, y no tengo la libertad de compartir tal
código. Además, aunque me es posible crear ejemplos para los artículos, simplemente no tengo tiempo de construir algo
más complejo que trabaje bien. Es algo que de fijo me gustaría lograr, pero simplemente no es práctico si quiero publicar
este artículo en un tiempo razonable.
El código fuente para el ejemplo puede ser descargado aquí.
También se le puede ver en acción abajo mediante escoger uno de los nombres y luego pulsar el botón Borrar. (La ligera
pausa durante la carga inicial y en la actualización del control luego de eliminar un contacto es simulada.)
La manera más fácil de aprender el patrón es por medio de observar la implementación de una aplicación completa. Yo
demuestro el proceso en MVVM with MEF in Silverlight. En el vídeo construyo algunos modelos de vista sencillos y muestro
una vista que es cambiada de forma dinámica dependiendo de la selección del usuario y uso MEF para hacer todas la
conexiones. Un caso más complejo es introducido en la segunda parte.
Pero, ¿qué hay de aplicaciones empresariales más complejas… las que tienen más que un solo botón, con múltiples vistas y
complicadas funciones y algoritmos? Eso va más allá de lo que se podría cubrir en detalle en este artículo; sin embargo,
quisiera discutir algunos problemas comunes y cómo los solucionaría yo usando MVVM.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 13/28
Escenarios comunes en MVVM
Por experiencia propia, la idea de enlazar comandos y modelos o propiedades es fácil de entender y aplicar. Son ciertas
situaciones específicas, como por ejemplo mostrar un cuadro de diálogo o activar una animación que se prestan a
confusión. ¿Cómo se pueden resolver esas dificultades comunes?
Lista con Selección
¿Cómo se puede adaptar el caso de una lista en la que se pueden seleccionar uno o más artículos usando MVVM? Resulta
que es bastante fácil. Imaginen un caso donde se tiene un ComboBox con una lista de nombres, y otra vista en la misma
página que muestra los detalles de la persona cuando es seleccionada. Si uso MEF para unir las dependencias (a la vez
mostrando una técnica diferente a la usada en la aplicación de ejemplo), el modelo de vista podría ser de la siguiente
manera:
public class ContactViewModel : BaseViewModel,
IPartImportsSatisfiedNotification
{
[Import]
public IContactService Service { get; set; }
public ContactViewModel()
{
Contacts = new ObservableCollection<Contact>();
}
public ObservableCollection<Contact> Contacts { get; set; }
private Contact _currentContact;
public Contact CurrentContact
{
get { return _currentContact; }
set
{
_currentContact = value;
RaisePropertyChanged("CurrentContact");
}
}
public void OnImportsSatisfied()
{
Service.FetchContacts(list =>
{
foreach(var contact in list)
{
Contacts.Add(contact);
}
CurrentContact = Contacts[0];
});
}
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 14/28
}
En este caso, importamos un servicio para obtener contactos, ensamblar la lista y asignar el contacto preseleccionado. El
cuadro desplegable está enlazado a la colección Contacts. La clave es que el nombre seleccionado también tiene un enlace
(es aquí donde el modelo de vista mantiene el estado):
...
<ComboBox ItemsSource="{Binding Contacts}"
SelectedItem="{Binding
CurrentContact,Mode=TwoWay}"/>
...
Lo que asegura que cada vez que un nombre es seleccionado en la lista, el contacto actual cambia. ¿Recuerdan que
mencioné que varias vistas pueden compartir el mismo modelo de vista? En este caso, la vista para los detalles del
contacto puede usar el mismo modelo de vista y crear enlaces con la propiedad CurrentContact.
Navegación
Otra situación enfrentada comúnmente es la navegación. ¿Cómo se puede controlar la navegación en una aplicación al
estilo MVVM? La mayoría de los ejemplos muestran un único botón en la pantalla y no lidian con aplicaciones compuestas
de varias páginas.
La respuesta corta es que, sin importar el mecanismo usado (ya sea usando un sistema propio, el provisto por Silverlight, el
administrador de regiones de PRISM o una combinación de todos los anteriores) se deberían ocultar los detalles tras una
interfase. Por medio de usar algo como INavigation o similar la navegación se torna ajena a MVVM. Cualquiera que sea el
modo escogido, el modelo de vista puede importar INavigation y usar la interfase para ir a otras vistas o generar un evento
de transición según sea necesario.
Mi artículo sobre el uso de MEF en lugar de PRISM demuestra cómo hacer esto usando la Infraestructura de Extensibilidad
Administrada. El artículo Auto-discoverable views using a fluent interface trata el uso de asociaciones entre vistas y
regiones, y Dynamic module loading with Prism provee una aplicación completa como ejemplo usando la infraestructura
de navegación.
Módulos dinámicos
Este caso es parecido al anterior. ¿Qué hay de aplicaciones extraordinariamente grandes? En tales situaciones tiene poco
sentido tratar de cargar toda la aplicación de una sola vez. El menú y pantalla principales deben ser visibles de inmediato,
mientras que los demás módulos se pueden cargar según sea necesario. El resultado es una reducción significativa en la
pausa inicial requerida para el arranque de la aplicación y también muestra respeto por el navegador de red y los recursos
de la computadora del usuario, como memoria y ciclos del CPU.
El cargado dinámico no es específico de MVVM, aún así el envío de mensajes entre modelos de vista y entre módulos es
obviamente importante. En estos casos me parece que es mejor usar infraestructuras como MEF y Prism que proveen
soluciones a problema. Prism tiene módulos que pueden ser cargados a pedido y MEF ofrece un catálogo de instalación
que permite cargar archivos XAP de manera dinámica. La solución de Prism para mensajes a través de la aplicación es la
central de eventos (event aggregator). Ofrezco más información sobre las infraestructuras y las soluciones para estos tipos
de problemas en el apéndice donde trato sobre las infraestructuras disponibles para uso inmediato.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 15/28
Cuadros de diálogo
Un artefacto usado frecuentemente en interfases gráficas es el cuadro de diálogo (similar al cuadro de mensajes, pero
esperando una respuesta del usuario). He visto a mucha gente estancarse tratando de implementarlos usando MVVM.
Especialmente al considerar la restricción en Silverlight de que todo el código debe ser asincrónico.
En mi opinión, la solución es encapsular el cuadro de diálogo tras una interfase y proveer una función de llamada para la
respuesta. El modelo de vista puede importar el cuadro y luego, basado en algún cambio de estado o un comando,
disparar el servicio de diálogo. La llamada de vuelta contiene la respuesta y la vista puede proceder apropiadamente.
Para una explicación más completa, pueden leer Simple Dialog Service in Silverlight.
Animaciones
Otro problema común es cómo activar animaciones o transiciones basadas en cambios en la interfase gráfica o en el
servidor.
Hay varias soluciones para el problema. Estos son algunos ejemplos:
El centralizador de estados visuales permite enlazar animaciones a eventos en la interfase gráfica sin la intervención
del modelo de vista. Si es necesario que éste último tenga parte en el asunto, entonces
Los delegados de animación pueden dar la talla. ¿Necesitan algo más autónomo? Pueden probar usando
La implementación del ICommand invertido de nRoute, o
Un infraestructura MVVM de muestra que usa el administrador de estados visuales.
Configuración y valores globales
Un problema que escucho comúnmente es cómo tratar con variables globales e información de configuración. De nuevo,
esto es menos un problema relativo a MVVM y más una decisión arquitectónica. En la mayoría de los casos, se puede hacer
disponible la información de configuración con una interfase (IConfiguration) y luego crear una implementación que
contenga los valores específicos. Cualquier modelo que requiera dicha información no tiene más que importar la
implementación, ya sea mediante MEF, Unity, u otro método similar, asegurándose de tener sólo una instancia de la clase
(tal vez usando el patrón de Instancia Única, aunque lo más probable es que sea controlado por el contenedor y no por la
clase misma).
Procesos asincrónicos
Otro punto de confusión con Silverlight es que todas la llamadas al servidor son necesariamente asincrónicas. Esto puede
parecer extraño al construir el modelo de vista: luego de generar la llamada, ¿cómo se puede saber cuando ha sido
completada? Generalmente se hace mediante subscribirse a un evento que es disparado al finalizar el proceso y los
resultados se obtienen mediante datos enlazados. Yo prefiero ocultar la los detalles del manejo de eventos tras una función
de tipo Action. El artículo Simplifying Asynchronous Calls in Silverlight using Actions muestra un ejemplo de cómo hacer
esto.
A veces el trabajo es más elaborado requiriendo múltiples llamadas asincrónicas que se deben ejecutar en secuencia y cada
una debe esperar a que la operación previa haya terminado. En tal caso, puede ser mejor investigar el uso de mecanismos
que facilitan escribir código para flujos de operaciones consecutivas. Este articulo explica una forma de hacerlo usando co-
rutinas, y este otro describe como usar una excelente infraestructura ya existente que maneja las llamadas manera segura
usando subprocesos, capturando errores, y mucho más.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 16/28
Conjuntos de datos inmensos
Por último, he escuchado aserciones de que MVVM no trabaja bien con grandes bancos de datos. Yo diría más bien que son
ciertas implementaciones las que presentan tal problema, no el patrón en sí. La solución frecuentemente es paginar los
datos, pero parece que muchos usan un enfoque incorrecto para resolver el problema. Por alguna razón, los desarrolladores
insisten en que la paginación es una función de la base de datos y debe ser aislada en la capa de acceso a datos. El simple
hecho de tener elementos como página actual y número de páginas en la interfase al usuario da a entender que tal no es
un artefacto de la base de datos, sino que está presente en todas la capas de la aplicación y debe ser manejado como tal.
En su forma más básica, se puede usar una colección que crezca a medida que el usuario pasa páginas. Si el conjunto de
datos es pequeño, se puede crear una sola colección y mantenerla por completo en el cliente Silverlight, usando un panel
virtual para desplegar la información (el problema con algunos paneles es que crean un control para cada elemento en el
conjunto entero de datos, destrozando la eficiencia—los paneles virtuales solamente crean los controles necesarios para
llenar la parte visible de la pantalla).
Tecnologías como WCF RIA son compatibles con consultas en LINQ. Este tipo de consultas contienen métodos de extensión
que permiten tomar únicamente los primeros elementos de una lista en vez de toda la lista de un solo. La infraestructura
también provee clases auxiliares como PagedCollectionView para ayudar a filtrar, ordenar y paginar datos.
Lo que MVVM no es
El tema no puede ser cubierto a cabalidad sin considerar lo que MVVM no es.
MVVM no es una infraestructura completa. Es un patrón de diseño y puede que algunas bibliotecas provean facilidades
para su implementación, pero no es más que una pieza de la entera solución para la arquitectura de la aplicación. MVVM
no está interesado en lo que ocurre en el servidor o la forma en que son implementados los servicios de soporte. En
cambio, y esto es una gran ventaja, su principal trabajo es la separación de responsabilidades.
En ninguna parte de este artículo van a encontrar la frase “MVVM no permite usar código subyacente”. El tema es
fuertemente debatido, pero el patrón en sí no indica cómo implementar la vista, ya sea con XAML, con código subyacente,
o una combinación de ambos. Mi sugerencia es que si están pasando días enteros escribiendo código tan sólo para evitar
algo que puede ser resuelto en unos cuantos minutos usando código subyacente, algo está mal.
MVVM no es requerido en WPF o Silverlight. A mi parecer, aplicaciones empresariales, de manejo de datos, o con múltiples
ventanas o formularios, son excelentes candidatos. Por otra parte, juegos, sitios Web de entretenimiento programas de
dibujo, y otros similares no se adaptan muy bien. Deben estar seguros de usar la herramienta apropiada para cada tarea.
MVVM no debería ser un motivo de retraso. Cualquier patrón o infraestructura requiere cierto tiempo de aprendizaje. Hay
que aceptar el hecho de que los desarrolladores tendrán que estudiarlo para poder entenderlo, pero lo que no es
aceptable es que el proceso entero de pronto dure más de la cuenta y termine atrasando el proyecto. El patrón es útil si, en
cambio, acelera el proceso de desarrollo, mejora la estabilidad y rendimiento de la aplicación, reduce los riesgos del
proyecto, y así por el estilo. Cuando lerdea el desarrollo, introduce problemas, y produce escalofríos en los desarrolladores
al oír su nombre, puede que sea necesario evaluar la forma en que se está ejecutando.
Conclusión
¡Ok, ya terminamos! Espero haberles ayudado a ver por qué MVVM es tan poderoso en aplicaciones Silverlight y WPF,
cuáles son los aspectos principales del patrón, y hasta haber mostrado ejemplos de soluciones a problemas comunes que
puede resolver. Ahora, quisiera conocer sus opiniones y comentarios.
Ir al Apéndice A: Orígenes de diversos patrones
Ir al Apéndice B: Infraestructuras disponibles
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 17/28
Mi agradecimiento especial a los siguientes miembros de la comunidad que dedicaron parte de sus ocupados horarios a
revisar y dar sus comentarios y sugerencias preliminares para este artículo (en orden alfabético):
Glenn Block (Gerente de programa en el departamento de .NET FX), @gblock, Blog
Lauren Bugnion (MVP para Silvelight), @LBugnion, Blog
Corey J. Gaudin. @CoreyGaudin, Blog, Facebook
Robert Kozak, @RobertKozak, Blog
Joe McBride, @XAMLCoder, Blog
Bill Moore, @CodenUX, Website
Joost van Schaik, @localjoost, Blog, LinkedIn
Davide Zordan (MVP para Silverlight), @DavideZordan, Blog
Apéndice A: Historia de algunos patrones
Modelo-Vista-Controlador (MVC)
Este patrón fue descrito primero en el contexto de Smalltalk en Xerox en 1979. Si lo desean pueden obtener algunos de los
documentos originales (en formato PDF) aquí.
Modelo-Vista-Presentador (MVP)
El patrón Modelo-Vista-Presentador (PDF) fue introducido en 1996 . Se basa en el MVC pero pone algunas restricciones en
el controlador cuyo nombre fue cambiado a presentador. Esta es su forma generalizada:
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 18/28
Martin Folwer describe el patrón con dos matices diferentes: El Contolador/Presentador superintendente y la Vista Pasiva.
Microsoft también da su propia descripción del MVP.
Modelo de presentación
En el 2004 Martin Fowler publicó su descripción para el Modelo de Presentación. El resumen es conciso: “Abarca el estado y
comportamiento de la presentación independientemente de los controles usados en la interfase gráfica al usuario.” Como
es evidente, MVVM es una forma especializada de este último patrón:
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 19/28
Apéndice B: Infraestructuras o bibliotecas de MVVM disponibles
Ahora que ya tenemos una idea de qué es MVVM, no es necesario reinventarlo. Hay varias bibliotecas ya existentes que
implementan MVVM. Sin ningún orden en particular:
MVVM Light
Este es un recurso muy popular que incluye entre sus facilidades, una clase base pasa modelos de vista, comandos,
mensajería, y platillas de proyectos para comenzar aplicaciones. Es compatible con WPF y Silverlight.
SilverlightFX
El objetivo de esta biblioteca es habilitar la creación de de interfaces al usuario usando un lenguaje declarativo,
permitiendo una más fácil separación entre la vista y el código, y lo hace mediante una biblioteca con sólo lo esencial.
Caliburn
Esta biblioteca popular usa la técnica de comenzar con el modelo de vista y es compatible con WPF y Silverlight. Sin
embargo, este es tan sólo un aspecto, puesto que es una muy completa infraestructura para la creación de aplicaciones.
nRoute
Otra biblioteca MVVM, con la especialidad de usar comandos reversos que permite enlazar comandos a eventos en la vista
a diferencia del modo corriente en que la vista envía comandos al modelo de vista.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 20/28
MicroModels
Un biblioteca enfocada a sólo lo estrictamente necesario para usar MVVM.
Composite WPF/PRISM
A pesar de que su nombre original es Composite WPF, la infraestructura es compatible con WPF y Silverlight. Y, aunque no
provee implementaciones del patrón MVVM, sí contiene guías y recursos para crear aplicaciones compuestas, incluyendo
comandos, centralización de eventos, administración de regiones visuales, y más.
La lista no es de ningún modo exhaustiva, pero espero que les dé una idea del apoyo que la comunidad Código Abierto le
ha dado al patrón MVVM. También les puede ayudar a escoger una biblioteca estable para acelerar el desarrollo de sus
aplicaciones.
Etiquetas asignadas: Jeremy Likness • MEF • MVVM • Silverlight • traducciones
21 Respuestas a “Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado”
1. Ricardo dice:
27 de Junio, 2010 en 10:39 am
Hola muy interesante tu articulo la verdad muy bien explicado , mira soy un programador de windowsforms y me
estoy educando en esto de el patron MVVM pero me ha costado mucho entender ya en la practica todos los
conceptos me interersa mucho aprender este patron u otro para desarrollar aplicaciones en WPF, he leido sobre
algunos frameworks como caliburn, calcium , que sesupone te ayudan desarrollar bajo este patron pero en mi caso en
vez de eso me revuelvo mas no se si me puedas dar una ayudadita diciendome donde puedo encontrar mas
ejemplos practicos del uso de este patron pues como te digo se meha dificultado mucho gracias !
Responder
David Mora dice:
27 de Junio, 2010 en 10:23 pm
Ricardo,
Gracias por el encomio. Quisiera poder publicar artículos con más frecuencia pero debido a estar muy
ocupado, se hace difícil. Aún así, estoy preparando una serie de artículos describiendo el proceso de crear un
aplicación usando ese patrón. A diferencia otros ejemplos, en este caso es una reseña sobre el diseño e
implementación de una aplicación real que está siendo usada por el cliente en este momento. Probablemente
tenga varias partes de la serie listas a mediados de Julio.
Desafortunadamente, ejemplos sólidos para MVVM son todavía escasos. La serie sobre MVVM y MEF de Shawn
Wildermuth provee algunos consejos prácticos. También es buena idea explorar el blog the Jeremy Likness.
Otra persona conocida por su pericia en MVVM es Josh Smith.
Responder
2. Ricardo dice:
28 de Junio, 2010 en 10:36 am
haa muchas gracias esperare estos articulos con ansiedad la verdad gracias ya que en español hay muy poco sobre
este patron y sobre los frameworks ni se diga practicamente no hay nada en español aunque eso no debe suponer
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 21/28
gran problema pero al menos a unos como yo no les caeria mal algo en español (mas comodo).
Ahorita me estoy adentrando a el framework MVVM Litght toolkit con C# ( soy un programador de VB.Net asi que me
cuesta algo ). la verdad espero puedas publicar porque se ve que realmente sabes mucho sobre este tema una vez
mas gracias!
Responder
3. Ricardo dice:
5 de Octubre, 2010 en 10:03 am
hola he seguido estudiando este articulo mas a detalle, nadamas que tengo un problema aun no logro entender estas
lineas de codigo del todo no se si me puedas explicar forman parte de la clase ContactModel.
public override bool Equals(object obj)
63 {
64 return obj is ContactModel &&
65 ((ContactModel) obj).FullName.Equals(FullName);
66 }
67
68 public override int GetHashCode()
69 {
70 return FullName.GetHashCode();
71 }
Responder
David Mora dice:
5 de Octubre, 2010 en 4:24 pm
Ricardo,
Tu pregunta es un tanto general, por lo que te ofrezco una respuesta general. Disculpa si explico conceptos que
ya conoces.
En .NET todas las clases tienen un antepasado común: Object. Tal descendencia es implícita, por lo que no es
necesario declararla. Eso quiere decir que ContactModel deriva de Object y hereda ciertos comportamientos de
esa clase fundamental. Una de las funciones heredadas es Equals. En su forma fundamental, el método compara
referencias. Es decir, Equals es cierto cuando ambas referencias apuntan al mismo objeto.
En el caso de ContactModel, el autor original (Jeremy) ha decidido que la igualdad debe ser evaluada a un
nivel conceptual: dos contactos son el mismo si su nombre completo es idéntico. Esto es debido a que se
puede dar la situación de tener dos objetos completamente separados que contengan el mismo nombre y la
función heredada de Object diría que son diferentes, lo cual no es cierto (por lo menos dentro de la reglas
establecidas por esta aplicación).
Un consecuencia de alterar el comportamiento de Equals, es que también se necesita modificar GetHashCode.
Esta función devuelve un valor cuasi-único para cada objeto y .NET lo usa para crear tablas de referencia tanto
internas como explícitas. El HashCode también es usado para evaluar la igualdad de objetos. En el caso
anterior, el autor ha tomado ventaja de que el código hash de una cadena de caracteres es calculado a partir
de la secuencia particular de la cadena. De esa manera, el valor obtenido es el mismo para cadenas idénticas.
Como puedes ver, nuevamente el valor depende del nombre completo del contacto.
Para más detalles puedes consultar las entradas para Object.Equals y Object.GetHashCode en MSDN.
En el artículo, el código no hace uso explícito de este comportamiento alterado, sin embargo, la regla sería útil
una vez que las funciones de añadido, búsqueda y borrado de contactos sean más sofisticadas.
Espero que la respuesta te haya ayudado. Si no lo hizo o si todavía tienes dudas, por favor déjame saber.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 22/28
Responder
4. Ricardo dice:
5 de Octubre, 2010 en 8:14 pm
Gracias que pena me da la verdad, al parecer me falta bastante por aprender, mira como te comentaba en respuestas
anteriores soy un programador de VB y la verdad C# me cuesta (mas bien no me gusta) estoy revisando el codigo de
ejemplo que adjuntaste en este articulo y la verdad me he quedado impresionado pues llevo ya varios meses
estudiando este modelo de programacion y aun no puedo atar los cabos sueltos, se que para este tipo de modelos
se requiere cierto nivel de conocimientos pero hay algunas cosas que aun no logro comprender por ejemplo . en el
codigo fuente vienen clases como el IService , Service,que aun no tengo muy claro cual es el papel que juegan,
ademas los Commands entiendo el concepto pero aun tengo problemas en su aplicacion perdona que te moleste
con conceptos tal vez muy triviales o tontos pero la verdad este es el unico lugar que he encontrado donde se han
respondido muchas de mis dudas.
Mira en estos meses desarrolle una humilde aplicacion en WPF tratando de aplicar este modelo pero al final me di
cuenta que lo hice todo mal ya que no pude desacoplar del todo las capas te presento un video de mi aplicacion,
http://www.youtube.com/watch?v=K8UULFUCIgQ
gracias! y espero me puedas seguir orientando.
Responder
5. Carlos dice:
10 de Noviembre, 2010 en 2:21 pm
Hola, me parece muy bueno tu articulo, mi consulta es que si para cada modelo debo crear un view model?, ya que
en mi aplicacion tengo varias tablas (unas 20) y debo crear una ventana de mantenimiento para cada una, entonces
trabajar con mvvm me lleva a crear 1 clase modelo por cada tabla mas 1 clase view model mas la vista esto es 3
clases por cada una, hay alguna manera de reducir esto o de acelerar el proceso? ya que las tablas tienen diferentes
campos y esto se me esta volviendo un problema, gracias
Responder
David Mora dice:
10 de Noviembre, 2010 en 7:19 pm
Carlos,
Algo que yo he hallado importante es tener en mente que se trata de un patrón y no una receta. La diferencia
es algo sutil, pero significativa. Una receta te da los pasos a seguir y desviarse del procedimiento tiende a ser
riesgoso. Un patrón, por lo menos en nuestro contexto, se trata de una estrategia a grandes rasgos, sin detalles
muy definidos. Uno tiene que rellenar donde falte. Es en parte por esto que los patrones son un poco difíciles
de digerir puesto que son necesariamente ambiguos. Otra consecuencia es que cada caso tiende a ser
diferente, incluso si se aplica el mismo patrón al dos soluciones diferentes, la arquitectura resultante casi de
seguro será distinta en cada caso.
El MVVM no dicta una correspondencia uno a uno entre modelo, modelo de vista y vista. No sería práctico
puesto que los tres se desenvuelven en entornos diferentes. Te digo de primeras que es común ver un modelo
de vista por cada vista, pero tampoco es una regla. La misma variedad se ven el caso del modelo. Algunos
consideran cada tabla, consulta o clase como un modelo. Otros agrupan diferentes entidades en modelos
conceptuales. Puesto que yo tiendo a diseñar usando la filosofía del DDD y BDD, mis modelos son más del
segundo tipo.
Bueno, luego de esta hablada, mi sugerencia es que examines tu aplicación desde el punto de vista de la
interfase gráfica. Si tienes por ejemplo páginas o pantallas en las que muestras varias tablas asociadas por un
concepto o tal vez una relación de maestro/detalle, las diferentes áreas de presentación pueden ser vistas (me
refiero a vista en MVVM) y usar un único modelo de vista que les sirva de puente al modelo. De hecho, usar un
modelo de vista común entre varias vistas es una estrategia a veces usada para proveer comunicaciones entre
la vistas (otra forma es mediante mensajería).
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 23/28
Como mencionas, el crecimiento desmedido en el número de clases puede ser fuente de muchos dolores de
cabeza en un futuro, y complica a veces el proyecto de manera innecesaria. Si tienes forma de combinar la
interacción de varios modelos usando un único modelo de vista, entonces ¡adelante! No obstante evita
acumular la llamada deuda técnica que se produce al desviarse de los principios SOLID.
Finalmente, aplicaciones de gestión en la que se provee una interfase gráfica para administrar una base de
datos tienden a ser un caso fronterizo. Es decir no se adaptan al modelo general “promedio” (por falta de
mejor expresión) de una aplicación RIA. Esto debido a que las tablas son vistas fuera de contexto. En tal caso, el
gran número de clases resultantes puede ser tedioso, pero no necesariamente nocivo puesto que no hay que
mantener relaciones complejas entre las entidades.
Responder
6. TJM: WPF, MVVM y Prism | Synaptic Way dice:
8 de Diciembre, 2010 en 1:58 pm
[...] La traducción de Maromas Digital del artículo de Jeremy Likness aquí. [...]
Responder
7. Introducción a Modelo-Vista-Modelo de Vista (MVVM) « El mundo magico de silverlight dice:
5 de Enero, 2011 en 6:56 am
[...] [...]
Responder
8. Christian Astúa dice:
8 de Enero, 2011 en 2:15 pm
Buenas. Muy interesante tu artículo. Estaba leyendolo pero en muchas cosas todavía estoy pérdido. Nunca he
programado en WPF, ya que yo sólo me dedicaba a Forms común y silvestres. El XAML por tags no es tan díficil, pero
me gustaría saber si este patrón puede aplicarse en forms normales. Es que no me queda tan claro la verdad y me
gustaría una pequeña luz para aclarar las cosas. Seguiré leyendo en inglés a ver si tambiéne so me ayuda.
De antemano muchas gracias por todo.
Responder
David Mora dice:
9 de Enero, 2011 en 8:00 am
Chistian,
Desde el punto de vista de ser un patrón de diseño, MVVM puede ser aplicado a Windows Forms. De hecho hay
varios ejemplos disponibles en la red y en libros (por ejemplo, este artículo en MSDN).
La última sección de esta página, menciona MVP en dos variantes, vista pasiva y el controlador superintendente.
Las diferencias son algo sutiles pero importantes. Entiendo que lees bien el inglés, por lo que te sugiero leer los
documentos enlazados en el apéndice para familiarizarte con los patrones envueltos. En fin, en términos
prácticos, el mecanismo disponible para enlace de datos tiene mucho que ver con el patrón específico que
mejor de adapte.
Para aplicaciones empresariales de cierto tamaño, Microsoft provee varias guías y una infraestructura completa
de diseño llamada Smart Client Software Factory. En el pasado usé una versión anterior (conocida como
Composite UI Application Block o CAB, ya obsoleta) y es buena pero, debido a la cantidad de infraestructura,
no vale la pena para aplicaciones pequeñas. No sé si la nueva versión es más liviana.
Lo que yo te sugeriría es separar tus objetivos. Ya sea aprender XAML junto con su sistema de enlaces de datos
(que, aunque comparten la idea general usada en Windows Forms, son mucho más efectivos y mejor portados)
sin preocuparte mucho por patrones de diseño hasta que ya tengas un poco de práctica, o seguir con Windows
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 24/28
Forms y estudiar los patrones de diseño hasta que estés familiarizado con sus características y aplicaciones.
Responder
9. La Liga Silverlight » Técnicas con MVVM dice:
4 de Febrero, 2011 en 8:41 am
[...] 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. [...]
Responder
10. Jounce, Parte 1: ¿Con qué motivo? | Maromas Digitales dice:
18 de Abril, 2011 en 10:02 am
[...] En las siguientes semanas voy a publicar una serie de artículos explicando un proyecto de fuente abierta que
acabo de lanzar llamado Jounce. Su proposito es suministrar guías sobre cómo crear aplicaciones modulares en
Silverlight usando la infraestructura de extensibilidad administrada (MEF por sus siglas en inglés) y el patrón Modelo-
Vista-Modelo de Vista (MVVM). [...]
Responder
11. MVVM Light Toolkit desde cero (paso 1) « Zitrodan's Blog dice:
29 de Mayo, 2011 en 7:11 pm
[...] http://maromasdigitales.net/2010/05/patron-mvvm-explicado/ [...]
Responder
12. Validación en WPF | Experiencias .NET dice:
3 de Julio, 2011 en 8:19 pm
[...] he usado el patrón MVVM para realizar este proyecto aunque no he seguido todos los [...]
Responder
13. La Liga Silverlight » MVVM Light Toolkit desde cero (paso 1) dice:
2 de Agosto, 2011 en 7:27 pm
[...] http://maromasdigitales.net/2010/05/patron-mvvm-explicado/ [...]
Responder
14. Ariel dice:
23 de Septiembre, 2011 en 7:31 am
Excelente artículo David. Solo quisiera preguntarte si conoces un buen libro que explice, en detalles o a fondo, todo
acerca de este y otros tipos de patrones. No importa si el lenguaje es en inglés o en español, aunque si es en español,
mejor aún.
Muchas gracias por tu tiempo y saludos fraternales.
Responder
David Mora dice:
23 de Septiembre, 2011 en 6:33 pm
Los patrones son estrategias para el diseño y construcción de aplicaciones. Un error común es buscar qué
patrones utilizar en un proyecto. La táctica correcta es busca la solución del problema y luego ver si hay
patrones que se amoldan al diseño general del programa o sistema.
El libro original que puso ne marcha el movimiento de patrones de diseño es Design Patterns: Elements of
Reusable Object-Oriented Software. Aunque ya es algo antiguo, es todavía válido y autoritario. Sin embargo su
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 25/28
lectura es difícil puesto que está escrito como tomo de texto y más como una referencia que una guía.
Para una introducción más suave al tema yo recomiendo los siguientes dos libros: Head First Design Patterns y
Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development. El
primero explica de una manera mucho más interesante varios de los patrones definidos en Design Patterns y
también presenta su aplicación. Aunque el segundo libro menciona UML en su título, no te dejes fastidiar por
eso. Si bien el tomo presenta aspectos de la notación en UML, también explica muy bien cómo uno puede
“encontrar” patrones a medida que construye la aplicación.
Hay otros libros, pero esos son útiles para empezar. Si sólo puedes obtener uno, yo sugiero Head First Design
Patterns.
Responder
15. Keni dice:
19 de Diciembre, 2011 en 5:33 pm
Muy buen articulo David, me gusto mucho la sencillez con la que explicaste el patrón, sin duda ayudará a mucha
gente a comprender su funcionamiento, pero sobre todo me gustaron tus conclusiones finales y los consejos y
advertencias.
Cada vez mas gente asocia WPF o Silverlight al uso obligado MVVM, complicándose el desarrollo en proyectos que
quizá se podrían haber resuelto de manera mas fácil. El uso de este patrón como el uso de cualquier otro, siempre
debe concebirse como una solución a un problema encontrado y no una receta para trabajar con una tecnología.
Debemos evaluar lo que MVVM nos ofrece y si es adecuado como solución a nuestro problema ya que
WPF/Silverlight nos ofrece un abanico de herramientas muy potentes que también podríamos usar para muy
diferentes y varados problemas; RoutedEvents, RoutedCommands, Separacion Árbol Lógico-Árbol Visual,
ControlTemplates, Lookless Control capabilities, Controles de Navegación, Animación/Medios, Interoperabilidad,
etcconclusiones finales y los consejos y advertencias sobre este.
Cada vez mas gente asocia WPF o Silverlight al uso obl
Responder
David Mora dice:
19 de Diciembre, 2011 en 10:19 pm
Gracias por tus comentarios. Debo, sin embargo, hacer énfasis en que es una traducción al español del artículo
por Jeremy Likeness. Aún así, estoy de acuerdo contigo en que Jeremy explica muy bien el tema, y su punto de
vista balanceado ha servido como guía, tanto para mí, como para muchos otros desarrolladores.
Responder
Responder
Nombre (opcional)
Email (opcional, no será publicado)
Sitio de Web (opcional)
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 26/28
Enviar Comentario
Materiales
Código Fuente
Ejemplo básico de MVVM (C#)
Artículos Recientes
Generando un modelo de clases en EF a partir de una base datos usando código primero
Jounce, Parte 3: Navegación básica
Guía para las nuevas características de Silverlight 5 Beta
Jounce, Parte 2: Comenzado (etiquetas y enlaces)
Jounce, Parte 1: ¿Con qué motivo?
T em as populares
Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado
Cómo generar una hoja de cálculo Excel en formato XML
Desarrollando con código primero en Entity Framework 4
Usando Entity Framework con Procedimientos Almacenados
Introducción a Silverlight - Parte 3: Acceso a datos
Silverlight, MVVM y WCF RIA Services: Notas de un proyecto real
Generando un modelo de clases en EF a partir de una base datos usando código primero
Introducción a Silverlight – Parte 2: Diseño de la interfase al usuario y navegación
Introducción a Silverlight – Parte 1: Herramientas y Hello World
De la base de datos al cliente con WCF RIA Services
Categorías
ASP.NET (2)
Blend (1)
Entity Framework (4)
Misceláneos (4)
Modelaje de Información (2)
Servicios RIA en Silverlight (15)
Silverlight (66)
Windows Phone (38)
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 27/28
Etiquetas
acceso a datos animaciones arquitectura ASP.NET MVC Blend Brad Abrams data binding DataSet depuración diseño visual
enlace de datos Entity Framework fundamentos guías prácticas hardware Jeff Blankenburg JeremyLikness John Galloway John Papa Jounce libros MEF modelos de información MVVM navegación ORM patrones de diseño
plantillas PRISM ria Scott Guthrie Shawn Wildermuth Silverlight Silverlight 3 Silverlight 4 Silverlight 5 Silverlight
Toolkit Tim Heuer tombstoning traducciones UX WCF RIA Services web services Windows Phone 7
T em as de Interés
My Fieldset
1. Sugiere un tema a cubrir en el blog:
Enviar
cforms contact form by delicious:days
Volver al Inicio »
Buscar por: Buscar
Archivo
Mayo 2011 (4)
Abril 2011 (3)
Marzo 2011 (2)
Febrero 2011 (2)
Enero 2011 (4)
Diciembre 2010 (31)
Noviembre 2010 (1)
Octubre 2010 (9)
Septiembre 2010 (1)
Agosto 2010 (2)
Julio 2010 (2)
Junio 2010 (1)
Mayo 2010 (3)
Abril 2010 (3)
Marzo 2010 (7)
Febrero 2010 (12)
Enero 2010 (7)
Licencia de uso
El contenido de las traducciones está sujeto a los términos de protección de derechos de uso de los autores originales quienes han
autorizado su publicación en este blog. Asegúrese de entender los terminos de la licencia de cada autor antes de usar tal contenido.
09/05/13 Patrón Modelo-Vista-Modelo de Vista (MVVM) Explicado | Maromas Digitales
maromasdigitales.net/2010/05/patron-mvvm-explicado/ 28/28
Mis propios artículos son publicados bajo los términos de la Licencia Reconocimiento-Compartir bajo la misma licencia 3.0 Estados Unidos
de Creative Commons:
Blog de Maromas Digitales by Maromas Digitales, LLC is licensed under a Creative Commons Reconocimiento-Compartir bajo la misma
licencia 3.0 Estados Unidos License.
License
The contents of all translated articles is subject to the copyright and licensing terms of the original authors and has been published here
with their express permission. Verify the original author's licensing terms before using the contents of these articles.
My own articles are licensed under the Creative Commons Attribution-Share Alike 3.0 United States License:
Blog de Maromas Digitales by Maromas Digitales, LLC is licensed under a Creative Commons Attribution-Share Alike 3.0 United States
License.
Portada
Artículos Por Autor
Acerca
Contactar
© 2010,2011 Maromas Digitales, LLC. Íconos de redes sociales creados por Komodo Media