¿Es buena idea agregar ViewModel exactamente igual que Model?

16

Tengo las siguientes capas en mi solución:

  1. App.Domain
  2. App.Service
  3. App.Core (tal vez llame a este App.DataLayer)
  4. App.Web

El patrón de diseño del software no es mi pregunta, tengo el siguiente modelo en Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Quiero usar este modelo en la vista (por ejemplo, página de inicio) Y quiero usar Id, Name & Value, así que si quiero crear ViewModel, agregaré lo siguiente:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Entonces, ¿es buena idea? o simplemente usar en Foolugar de FooViewModel?

Mehdi Dehghani
fuente
No estoy seguro de entender esto. ¿No Modelse pasa generalmente a la View? ¿Por qué exactamente necesita recrear los campos de Modelen el View? Si el objetivo es la separación de las preocupaciones MVC, ¿en qué circunstancias querría hacer lo mismo con Modely View? Si ViewModeles ambos, ¿por qué no extendiendo / componiendo ambos Modely View?
nulo el
por favor lea mis comentarios sobre la respuesta de @ svidgen
Mehdi Dehghani
Tengo un problema relacionado, donde la validación (atributo requerido) en los modelos (y en la base de datos) indica que se deben ingresar ciertos valores, pero en las vistas, esos valores no es necesario, por lo que me veo obligado a copiar algunos campos de los modelos en el modelo de vista, en lugar de hacer referencia al modelo directamente. Sin embargo, en la reflexión, esto probablemente está bien y, de hecho, no viola DRY, ya que son para diferentes propósitos (de todos modos, no tan mal).
niico

Respuestas:

20

Esto puede parecer una violación de la regla DRY inicialmente, pero diría que un código "similar e incluso idéntico" no es necesariamente una "repetición" si hace algo diferente o puede cambiar de forma independiente. Y en el caso de los modelos de vista, el código define lo que ve el "cliente", no necesariamente las entidades y operaciones de las que habla el negocio. Por lo tanto, a menudo revela modelos al cliente o interfaz que son "incidentalmente idénticos". Puede cambiar las reglas y términos comerciales o la terminología del usuario final independientemente uno del otro.

Entonces, volvería a hacerte la pregunta. Si el dominio cambia, ¿es aceptable que los clientes de la "versión 1" sigan usando las interfaces antiguas? ¿Revelarás alguna vez términos u operaciones en la interfaz que no formen parte de las "reglas comerciales básicas"? ¿Y viceversa?

Ese tipo de preguntas en mente, si la "función" de su vista es revelar estrictamente el modelo de dominio subyacente, sí, parece que viola la regla DRY.

También tenga en cuenta que exponer una visión que cambia más naturalmente con los cambios del modelo también se puede lograr en algunos idiomas con atributos y reflexión de miembros. (O con menos repetición a través de otras hazañas de inteligencia ... Pero, la "inteligencia" a menudo no puede justificar la repetición que te ahorra).

svidgen
fuente
Buenas notas mencionadas (vote por esto), como dije como comentario en la respuesta anterior, estoy hablando de propósito general, imágenes, tal vez algunos días después, decidí agregar un nuevo campo / propiedad Foo, así que si lo usaba Foocomo ViewModel también, el cliente obtendrá nuevas propiedades también, entonces, ¿qué pasa si este nuevo fuera un campo de seguridad (tal vez verdadero / falso para obtener permiso, o algo así), ¿qué debo hacer?
Mehdi Dehghani
@mehdi necesitará ser más específico sobre qué campo está pensando agregar y por qué cree que pertenece o no a la vista. O, en general, cuál es la preocupación allí.
svidgen
@mehdi para ser claro, si le preocupa que los usuarios finales cambien un valor de seguridad, su dominio simplemente no debería permitir que los usuarios guarden cosas que no están autorizados a guardar
svidgen
¿Por qué usamos ViewModels? Hay algunas razones, como sabemos, una de ellas es por seguridad, por ejemplo, enUser edit form , no necesitamos pasar el IsAdmincampo al cliente, para mantener este campo seguro, así que esto es lo que me preocupa. Perdón por mi mal ingles.
Mehdi Dehghani
1
Dicho de otra manera, creo que la pregunta original es una pregunta completa. La pregunta que está tratando de resolver en los comentarios aquí es otra pregunta completa. Y los comentarios no son una buena manera de obtener respuestas buenas y de calidad.
svidgen
2

Tendría un modelo de vista que contiene solo una propiedad, una instancia de Foo. De esa manera, no está violando DRY de acuerdo con ninguna definición de este, si Foo cambia, su modelo de vista ve automáticamente el cambio y se libera de un vínculo directo del modelo de vista con el modelo.

Si mañana es necesario que la vista muestre algo más, así como el Foo, puede agregar una nueva propiedad, y la intención de su modelo de vista seguirá siendo clara, contiene un Foo y algo más, no tendrá Una mezcla de propiedades de Foo con otras propiedades no relacionadas.

No pensaría en su modelo de vista como un FooViewModel, lo pensaría en términos de lo que se supone que debe mostrar la vista. Si solo muestra un Foo, el modelo de vista contiene una propiedad, un Foo.

No estoy seguro si lo expliqué claramente. Si no es así, ¡hágamelo saber y trataré de reformularlo cuando esté despierto!

Avrohom Yisroel
fuente
-2

Yo diría que usar FooViewModelde esta manera viola el director DRY. Cuando necesite hacer un cambio Foo, también debe hacerlo FooViewModel. Creo que sería mejor servirlo simplemente Foocomo modelo para su vista. Consideraría un modelo de vista si necesita mostrar cosas de Foo y algo más. Por ejemplo, supongamos que necesita representar cierta información desde Fooy también desde Bar.

zero_dev
fuente
Por favor, dígame, si decidí agregar otro campo / propiedad al Foo, así que debido a que también utilicé Foocomo ViewModel, así que también tengo que pasar este nuevo campo a la vista, creo que este no es un buen negocio, ¿qué cree? ?
Mehdi Dehghani
No veo nada malo en que la Vista use solo un subconjunto de los datos expuestos por el modelo. Creo que la mayor falta es el acoplamiento entre Fooy FooViewModel. En general, no es una buena idea tener que modificar varios archivos para un solo cambio lógico.
zero_dev
¿Qué pasa si ese campo agregado era un campo de seguridad, como un true/falsevalor para el permiso o algo así?
Mehdi Dehghani
No tiene que exponer dichos campos en la Vista en sí, pero debe asegurarse de que el resto de su código no permita al usuario cambiar su nivel de seguridad, en caso de que un usuario malintencionado intente PUBLICAR dicho cambio.
Graham
Parece que estaría abierto a ataques de asignación masiva
James