2010-04-14 11 views
10

El objetivo de M-V-VM como todos sabemos es acerca de la preocupación por las preocupaciones. En patrones como MVVM, MVC o MVP, el objetivo principal es desacoplar la vista de los datos y, por lo tanto, construir componentes más flexibles. Primero demostraré un escenario muy común que se encuentra en muchas aplicaciones de WPF, y luego expondré mi punto:M-V-VM, ¿no se está filtrando el modelo en la vista?

Digamos que tenemos alguna aplicación StockQuote que transmite un montón de citas y las muestra en la pantalla. Por lo general, tendría la siguiente:

StockQuote.cs: (Modelo)

public class StockQuote 
    { 
     public string Symbol { get; set; } 
     public double Price { get; set; } 
    } 

StockQuoteViewModel.cs: (ViewModel)

public class StockQuoteViewModel 
    { 
     private ObservableCollection<StockQuote> _quotes = new ObservableCollection<StockQuote>(); 

     public ObservableCollection<StockQuote> Quotes 
     { 
     get 
     { 
      return _quotes; 
     } 
     } 
    } 

StockQuoteView.xaml (Ver)

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="Window1" Height="300" Width="300"> 
    <Window.DataContext> 
     <local:StockQuoteViewModel/> 
    </Window.DataContext> 
    <Window.Resources> 
     <DataTemplate x:Key="listBoxDateTemplate"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Symbol}"/> 
       <TextBlock Text="{Binding Price}"/> 
      </StackPanel> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <ListBox ItemTemplate="{StaticResource listBoxDateTemplate}" ItemsSource="{Binding Quotes}"/> 
    </Grid> 
</Window> 

Y luego tendría algún tipo de servicio que alimentaría a ObservableCollection con nuevas StockQuotes.

Mi pregunta es esta: en este tipo de escenario, el StockQuote se considera el Modelo, y lo estamos exponiendo a la Vista a través del ObservableCollection de ViewModel. Lo que básicamente significa que nuestra Vista tiene conocimiento del Modelo. ¿Eso no viola el paradigma completo de M-V-VM? ¿O me estoy perdiendo algo aquí ...?

Respuesta

3

No. No está exponiendo StockQuote. Solo está especificando una interfaz (sin tipeo) en la vista. La vista solo conoce dos propiedades: símbolo y precio. Puede reemplazar fácilmente a StockQuote con cualquier otro, siempre que implemente esos.

+0

Ese es un buen punto, aunque depende de la naturaleza "suelta" de WPF Data Binding. Sin embargo, si hubiera escrito una prueba unitaria para la VM que dependía de la colección StockQuote, se rompería si cambiara la clase StockQuote. –

8

Estoy más familiarizado con MVC que con MVVM, pero generalmente se acepta que la Vista tendrá conocimiento del Modelo. Siempre que el Modelo no tenga conocimiento de la Vista, está bien.

Si esto realmente es una preocupación por alguna razón, consulte el diseño de "Vista pasiva", donde la vista no sabe nada más que los datos brutos que se le suministran.

+5

exactamente lo que iba a escribir. La vista tiene que saber * algo * sobre el modelo; de lo contrario, ¿a qué se debe? – timdev

7

En MVVM, el modelo de vista es algo entre la vista y el modelo que expone los datos del modelo de una manera que la vista puede manejar fácilmente. En una aplicación MVVM estricta, la vista no conoce el modelo, solo el modelo de vista.

En el ejemplo concreto del modelo de vista no debería ser llamado StockQuoteViewModel pero StockQuotesViewModel (tener en cuenta el plural) debido a que el modelo de vista es la exposición de muchas cotizaciones de acciones por una colección de interfaz de usuario específica que es fácil de manejar por la vista (porque ObservableCollection<T> implementa INotifyCollectionChanged<T>). El tipo de elementos en la colección debe ser un modelo de vista (por ejemplo, StockQuoteViewModel) que expone datos de un único objeto StockQuote. En dicho modelo de vista puede agregar lógica, como agregar un $ -símbolo a Price y así sucesivamente.

A menudo es más fácil exponer algunos objetos de modelo en un modelo de vista, pero la forma correcta sería crear un modelo de vista para cada clase de modelo.

Best Regards,
Oliver Hanappi

0

Tal vez tienen esta mal, pero no es la idea del modelo de vista para encapsular el modelo completo. Por ejemplo, tiene cotizaciones de acciones expuestas a la vista, pero se deben mapear a propiedades nativas del modelo de vista que luego se vincularán.Esto es para necesitar "limpieza" que podría ser necesaria durante la transferencia de datos al modelo/vista.

De esta manera, la vista solo conoce el modelo de vista. También significa que si el modelo no fue heredado, podría implementarse como una interfaz y reducir aún más el acoplamiento entre el modelo de vista.

1

Mi entendimiento es que ViewModels son para Modelos como Propiedades para Campos. Esta es una analogía muy flexible, pero implica que no está aislado adecuadamente si su Vista está accediendo directamente a su Modelo. Al igual que con las propiedades triviales en una clase que envuelve campos privados, se obtiene una gran cantidad de duplicaciones y un código repetitivo cuando se envuelven las propiedades relevantes del Modelo en las propiedades de ViewModel para su consumo por la Vista. Esto es algo que me molesta con este patrón y todavía no estoy decidido si los beneficios valen la pena.

En este ejemplo en particular, creo que sería excesivo crear una máquina virtual para cada instancia de StockQuote, ya que es probable que no haga ninguna lógica significativa para la vista que representa una acción individual. Creo que es mucho más limpio y más fácil de mantener en estos casos pequeños para simplemente enlazar directamente a la clase Model. Crear una máquina virtual para el caso pequeño reduciría el acoplamiento, pero también aumentaría la complejidad y creo que es una decisión de caso por caso en cuanto a si esto es beneficioso.

Cuestiones relacionadas