2010-04-16 7 views
10

Continúo luchando con el patrón MVVM y, al intentar crear un diseño práctico para un proyecto pequeño/mediano, me he encontrado con una serie de desafíos. Uno de estos desafíos es descubrir cómo obtener los beneficios del desacoplamiento con este patrón sin crear muchos códigos repetitivos y difíciles de mantener.MVVM: modelos de vista finos y modelos enriquecidos

Mi estrategia actual ha sido crear clases de modelos 'ricas'. Son plenamente conscientes de que serán consumidos por un patrón MVVM e implementarán INotifyPropertyChanged, permitirán que se observen sus colecciones y se mantendrán conscientes de que pueden estar siempre bajo observación. Mis clases de ViewModel tienden a ser delgadas, solo exponen propiedades cuando los datos realmente necesitan transformarse, y la mayor parte de su código son los manejadores de RelayCommand. Las vistas se unen alegremente a ViewModels o Models directamente, dependiendo de si se requiere alguna transformación de datos. Utilizo AOP (a través de Postsharp) para aliviar el dolor de INotifyPropertyChanged, por lo que es fácil hacer que todas mis clases de modelos sean 'ricas' de esta manera.

¿Existen desventajas significativas al usar este enfoque? ¿Puedo suponer que ViewModel y View están tan estrechamente acoplados que si necesito una nueva transformación de datos para View, simplemente puedo agregarlos al ViewModel según sea necesario?

Respuesta

6

Creo que INotifyPropertyChanged en su modelo solo es útil cuando está esperando que sea operado por su VM y por "fuerzas" externas simultáneamente.

Personalmente soy partidario de los modelos POCO. Poner cualquier andamio específico de framework en mi modelo me haría preocuparme. Cuando coloca un evento en su clase de modelo, debe considerar cuidadosamente los posibles problemas con el ciclo de vida, serialización, almacenamiento, etc. de su modelo. Por ejemplo, ¿qué ocurre si recrea su objeto desde el origen de datos y las suscripciones antiguas INotifyPropertyChanged ahora no son válidas?

Similarmente, el mejor lugar para ObservableCollection es en la VM, que puede consumir un origen de datos IEnumerable, y presentar a la vista solo elementos filtrados seleccionados o ad hoc.

+0

'Fuerzas' externas es una buena descripción de cómo funciona actualmente mi diseño. Mi VM está transformando el Modelo (si es necesario) para la Vista, pero la VM, otros Modelos o una VM completamente diferente que interactúa con él de otra manera pueden actuar sobre el Modelo. Si una extensión de herramienta agrega un cable en mi modelo, me gustaría que todas mis VM y vistas miren el cableado para ver el cambio. Creé colecciones personalizadas que monitorean el Model ObservableCollections para proporcionar un filtrado especial (más allá del solo filtro de CollectionView), pero la mayoría de las veces me vinculo al Model ObservableCollection. –

3

Considero que este es el enfoque pragmático: hemos seguido este patrón con éxito en el pasado.

La premisa básica era vincular directamente a un modelo que implementa INotifyPropertyChanged para la mayoría de los datos de solo lectura, y luego agregar propiedades adicionales al modelo de vista para ver cosas específicas que se deben transformar (como sugirió). Para las propiedades que no son de solo lectura, encontramos que es más fácil crear las entradas de viewmodel (generalmente de tipo cadena) ya que esto permite que la validación del lado del cliente se agregue fácilmente en el modelo de vista.

+2

¿Ha hecho la transición a un patrón diferente ahora?¿Hubo cosas específicas que aprendió como resultado de este enfoque anterior que sugirieron la necesidad de cambiar su enfoque? –

0

Acepto que habrá un acoplamiento estricto entre View y ViewModel. Pero esto se puede aliviar hasta cierto punto utilizando IValueConverters siempre que sea posible para realizar transformaciones.

Intento mantener mi lógica empresarial en mi ViewModel. Además, utilizo Viewmodel para cambiar la forma de mi modelo para que se ajuste a lo que la vista podría esperar.

+1

esto parece muy incorrecto ... – vidalsasoon

3

Renuncia - Yo no soy un experto -

no pongo INotifyChanged en mis modelos. Había hecho esto al principio, pero me di cuenta de que INotifyChanged es realmente práctico para notificar a la IU, así que ahora solo coloque INotifyChanged en mis ViewModels. Esto ha hecho que sea más fácil controlar el número de "RaisePropertyChanged" ... Mis vistas nunca hacen referencia directamente a un Modelo.

estoy trabajando en mi primer proyecto MVVM sin embargo, en mi tercera refactor importante: P

Cuestiones relacionadas