¿Alguna razón para usar el modelo DTO (ORM autogenerated stuff) como ViewModel?

7

He encontrado una vez más esta situación en la que los programadores utilizan modelos generados automáticamente (desde LinqToSql, EF, nHibernate, lo que sea) como modelos de vista.

Generalmente la arquitectura es muy simple:

  1. Algún tipo de DAL que contiene solo EF o LinqToSql
  2. Algunos módulos para cosas muy específicas
  3. proyecto MVC

Puede o no contener un repositorio. De cualquier manera, los modelos DAL se utilizan como modelos de vista. El número de propiedades utilizadas de dicho modelo varía de 10% a 90% por vista, aunque generalmente se usan menos del 75% de las propiedades.

Recientemente he encontrado una nueva mutación de dicho patrón, donde cuando el modelo DTO carece de un campo adicional requerido, un programador crea un modelo de vista que hereda el modelo EF y lo pasa a la vista.

¿Hay tutoriales presionando para este enfoque? ¿O algunos libros o 'entrenadores' empujándolo? ¿Hay alguna razón sensible al lado de "soy perezoso"? ¿Tengo una impresión totalmente errónea y este es un patrón correcto y aceptado?

    
pregunta Michał Brix 04.05.2017 - 16:06

4 respuestas

6

Desde un punto de vista de seguridad, debe usar una vista 1 a 1 para ver el modelo y solo pasar las propiedades que la vista necesita. Si utiliza la clase ORM completa, un usuario malintencionado podría publicar manualmente elementos adicionales y modificar los datos que no pretendía modificar (dejando de lado cualquier servidor de validación adicional que no sería necesario si la propiedad no estuviera disponible en primer lugar). Al pasar solo los datos necesarios para la vista, elimina este posible vector de ataque al no exponer los parámetros adicionales.

Junto con el aspecto de seguridad que tiene modelos de vista separados de las clases ORM presenta una interfaz clara entre las cosas. En Razor (.net), si cambiara una clase de ORM de una manera que creara un error, solo se mostraría en el tiempo de ejecución donde, como si hubiera una asignación que ocurriera entre el ORM y el Modelo de vista (manual o automático), Tendría una mejor oportunidad de presentar un error de compilación.

Sí, hay ocasiones en que esto creará clases duplicadas, pero vale la pena duplicarlas porque las clases podrían cambiar de forma independiente por diferentes motivos.

    
respondido por el WindRaven 04.05.2017 - 23:15
7

No hay estándares claros sobre cómo estructurar la capa "M" de una aplicación MVC. Dicho esto, siempre he encontrado problemas con el uso de clases de negocio (o modelos de dominio o modelos ORM) en la capa de visualización de una aplicación.

  • La lógica de visualización se filtra en clases de negocios
  • La lógica de visualización se salpica en todas las plantillas de vista
  • No hay una indicación clara para el programador de lo que es absolutamente necesario para generar una vista
  • Las validaciones específicas de la presentación terminan contaminando las clases que no están destinadas a ser sobre la presentación
  • Las clases de negocios se modifican para permitir datos no válidos de acuerdo con las reglas de negocios, porque la clase se usa para representar un formulario (y, por lo tanto, debe permitir que se ingresen datos no válidos)

    ¡Esta es la gran razón para separar los modelos de vista de las clases de negocios!

Por esta razón, casi siempre creo modelos de vista para mis vistas, aproximadamente el 99% del tiempo. No hay mucho esfuerzo adicional para crear un modelo de vista, y le da un lugar para poner la lógica específica de la presentación. Tener esa separación en su lugar desde el día 1 evita una refactorización inminente más adelante cuando se expanden las necesidades de la interfaz de usuario.

Esta refactorización ocurre. Cada. Soltero. Tiempo.

Incluso si sus clases de negocios y modelos de vista tienen exactamente las mismas propiedades, está bien copiar datos. No está bien copiar la lógica. Y no está bien combinar la lógica de presentación con la lógica de negocios (o la lógica de almacenamiento de datos).

La separación de modelos de vista y clases de negocios se reduce a Separación de preocupaciones y es simplemente un diseño orientado a objetos.

En marcos como ASP.NET MVC que usan plantillas de Razor, no obtiene errores de compilación en sus vistas cuando cambia el nombre de una propiedad o nombre de clase, lo que complica la refactorización. Si tiene un modelo de vista, sus clases de negocios pueden ser refactorizadas como mejor le parezca, y obtendrá errores de compilación en sus modelos de vista por cambios incompatibles.

Si usaste tus clases de negocios directamente en tus vistas, obtienes un error en el tiempo de ejecución, que es más difícil de depurar y demora más en desentrañar.

Con respecto a YAGNI (no lo vas a necesitar)

El principio YAGNI nos dice que no construyamos cosas que son innecesarias. El problema es que las interfaces de usuario y las reglas de negocios experimentan muchos cambios durante la vida de una aplicación. Separar a los dos en sus propias clases no está violando a YAGNI. Recuerda no solo pensar en "Hoy". Las cosas van a cambiar, y separar los modelos de vista de las clases de negocios le da una zona de amortiguamiento entre estos dos tipos de cambios.

    
respondido por el Greg Burghardt 04.05.2017 - 16:49
2

Ser perezoso puede ser un punto perfectamente válido porque:

  • Producir más código hace que se mantenga más código, lo cual es bastante triste si es totalmente innecesario (YAGNI: No lo vas a saber)
  • Si su ORM usa almacenamiento en caché, funcionará mejor con el objeto completo que con la selección de columnas específicas en las tablas, no se almacenarán en caché, por lo que es muy probable que termine consultando su base con más frecuencia.
  • Heredar el dto para la vista evita copiar / pegar

Por supuesto, esto no es gratis, costará un acoplamiento más estricto y un inconveniente, como si consultara dos objetos de diferente tipo (sin un vínculo de composición / agregación entre ellos) por separado, donde podría tener una combinación si el objeto de su vista está separado del uno de dto.

    
respondido por el Walfrat 04.05.2017 - 16:29
0

El propósito de MVC es separar la lógica del dominio de la lógica específica de la UI.

La versión estándar de MVC tiene tres componentes. Los componentes de Vista y Controlador definen la interfaz de usuario (presentación y operaciones respectivamente), mientras que el Modelo es algún tipo de modelo de dominio que es independiente de cualquier IU específica.

El patrón MVC no dice nada acerca de lo que debería ser el modelo, excepto que no debe contener lógica específica de la interfaz de usuario. Por lo tanto, usar objetos de la base de datos como modelo es totalmente correcto de acuerdo con esto.

Ahora al núcleo de su pregunta:

  

Recientemente he encontrado una nueva mutación de dicho patrón, donde cuando   El modelo DTO carece de un campo adicional requerido, un programador crea un   ver el modelo que hereda el modelo EF y pasarlo a la vista.

Bueno, esto depende de lo que es el campo adicional! Si es algún tipo de lógica de dominio (por ejemplo, un campo calculado) lo que es independiente de los problemas de la interfaz de usuario, entonces está bien . Si el campo es algo específico de la interfaz de usuario, entonces es malo , porque cualquier elemento de la interfaz de usuario debe pertenecer a la capa de la vista o del controlador, no a la capa del modelo, y al subclasificar una clase de modelo, este campo se vuelve tenso. acoplado al modelo.

    
respondido por el JacquesB 06.05.2017 - 11:57

Lea otras preguntas en las etiquetas