2010-01-02 11 views
6

En varios proyectos de ejemplo, he visto que ViewModels se usa para convertir objetos de datos en cadenas, para usar en la Vista.ViewModels y rendering

El ViewModel generalmente tendrá un constructor que reciba un parámetro: un objeto de datos. El constructor completará varias propiedades del ViewModel (principalmente cadenas y puntos).

Esto evita que ocurra una lógica compleja en la Vista.

A primera vista, esto me parece una buena idea, ya que obliga más a la separación de la Vista de la lógica compleja.

Por ejemplo, supongamos que mi vista intentaba representar una propiedad 'Tamaño' de un objeto de datos, que es un número entre 1 y 3 que representa 'Pequeño/Medio/Grande'.

En lugar de tener una declaración if/switch en mi vista, simplemente tendría un 'SizeString' o algo similar en mi ViewModel, y la instrucción if/switch iría en el constructor de ViewModel.

¿Alguien está en desacuerdo con este enfoque?

¿Sería mejor utilizar algún otro enfoque, como los ayudantes? Y si es así, ¿por qué?

Respuesta

6

El objetivo del ViewModel es representar (una parte de) el complejo Modelo de dominio descompuesto como primitivas que se pueden representar de una forma u otra.

Esta descomposición debe tener lugar en algún lugar. Puede implicar algún tipo de lógica sencilla, como mi ejemplo favorito: la conversión de un valor discreto (OK , advertencia, error ) en colores (verde, amarillo, rojo). Esta es la esencia de lo que hace un ViewModel, por lo que mi enfoque predeterminado sería encapsular esta lógica en el ViewModel mismo.

Considere la alternativa: Si no está implementado en ViewModel, ¿dónde? Si pones la lógica en otro lugar, terminas con un ViewModel que es básicamente una estructura sin lógica. Permitir que un modelo de vista encapsule la transformación/descomposición de un objeto de dominio se adapta bien al Single Responsibility Principle.

Aunque este es mi enfoque predeterminado, siempre estoy consciente de que la lógica puede necesitar ser reutilizada en múltiples modelos de vista. En tales casos, esto puede ser una indicación de que el ViewModel original es realmente un ViewModel complejo compuesto por varias sub-vistas. En tales casos, puede extraer la lógica común en un submodelo ViewModel que encapsula solo esa pequeña parte.

+0

Buena explicación. La razón por la que no estaba seguro de esto era porque estoy seguro de que leí en alguna parte que los Modelos de Vista deberían ser simples objetos POCO sin ninguna lógica. Pero claramente esto no funcionaría. Se debe permitir que ViewModels contenga lógica de presentación. – Jonathan

+0

POCO no excluye la existencia de lógica :) –

+0

Quería escribir sobre SRP, pero ya lo hizo. Como siempre digo, es difícil ser boxeador y bailarín de ballet simultáneamente. :) –

2

Convierte todo en una cadena porque todo en la web es una cadena.

Básicamente: se supone que el modelo de vista está en estado 'listo para imprimir'. Si la web se hiciera únicamente con números, transformaríamos todo en ints/decimales.

Punto de vista completoModelo: para formatear datos representables. En su caso, tamaño enum a pequeño/mediano/grande. No es que separar la lógica de las vistas lo hace valioso, es la capacidad de adaptar sus datos para la web de una manera, un lugar.


Respondiendo a comentar =>

Sí, que se sienta bien. Estoy haciendo lo mismo. Pero hay que mencionar que no estoy en contra de poner eso en puntos de vista también. Porque las vistas y los modelos de visualización son los últimos en 'cadena de dependencia'. Soy bastante pragmático y completamente contrario solo a las situaciones cuando el desarrollador utiliza el modelo de dominio como modelo de vista y los requisitos para el modelo de vista entran en conflicto con el modelo de dominio (es decir, cuando el desarrollador agrega nuevos "objetos de dominio" solo con fines representativos).

+0

En realidad, ya lo implementé como Enum, pero excluí este hecho para no complicar demasiado el ejemplo. Por supuesto, si solo dejo que la Vista acceda directamente a Enum, todavía habrá lógica para convertirla en una cadena, como por ejemplo: "Enum.GetName (...)". Por lo tanto, preferiría exponer la propiedad como una cadena en ViewModel y dejar que ViewModel se encargue de la conversión de la cadena enum. ¿Estaría bien con usted? – Jonathan

+0

actualizó mi respuesta ... –