En un sistema MVC, ¿dónde debería ubicarse el código de persistencia de la base de datos?

21

He visto múltiples configuraciones para la información persistente en la base de datos. En general, tres tipos de diseños parecen comunes en mi rincón del mundo:

  • El controlador maneja la persistencia
  • Modelo maneja la persistencia
  • La biblioteca de terceros gestiona la persistencia, que generalmente requiere algún tipo de anotaciones en el modelo.

Me pregunto qué configuración (si existe) es, conceptualmente, la más fácil de usar / más compatible con una arquitectura MVC.

(Si no es uno que enumeré, proporcione un resumen / resumen rápido como parte de la respuesta)

blueberryfields
fuente

Respuestas:

13

Su segunda y tercera opción son idénticas. La M en MVC no es el modelo de datos, sino el modelo de dominio. Esto incluye la persistencia, ya sea directamente o mediante un ORM, y ambos son perfectamente correctos.

El controlador debe administrar el flujo del sitio y pasar cosas al dominio (a veces a través de una capa de servicio) para que se manejen, por lo que persistir desde allí es incorrecto, o al menos semánticamente incómodo.

pdr
fuente
2
No estoy de acuerdo en cierta medida. La utilización concreta de la persistencia es la lógica de la aplicación y, por lo tanto, pertenece a una capa de aplicación y no a la capa de dominio. La capa de dominio (que contiene el modelo de dominio) debe ignorar la persistencia del programa informal de negocios. El controlador es un orquestador . Puede orquestar servicios (datos), la interfaz de usuario y el modelo de dominio.
Falcon
1
@Falcon: Si bien el controlador debe controlar cuándo se cargan y persisten los datos en la base de datos, está perfectamente bien que le diga al modelo que lo haga. Usar un ORM (estándar o roll-your-own) generalmente significa decirle al modelo que cargue / guarde, que luego delega en el ORM. Otra forma podría ser hacer que el controlador le diga a un ORM que cargue / guarde algo pasándole una clase de modelo para cargar (con criterios de selección) o una instancia de modelo para guardar. De cualquier manera, la carga / guardado real estará directamente vinculada al modelo.
Marjan Venema
@Marjan Venema: Sí, estoy de acuerdo, pero la pregunta es dónde debería vivir ese código. Me esfuerzo por mantener el modelo lo más ignorante posible de la persistencia y solo modelar las entidades de dominio con sus comportamientos e interacciones. Cualquier otra cosa vivirá en capas de aplicación (ya que es una aplicación de mi modelo). La información de mapeo / acceso a datos está completamente desacoplada del modelo de dominio y también puede encargarse del control de versiones (actualización / degradación). La aplicación de acceso a datos también se encuentra en capas de aplicación (que contienen servicios, repositorios, etc.)
Falcon
@Falcon: Sí, esa es una buena manera de hacerlo y así es como lo hice en el pasado usando clases de mapeo separadas. Sin embargo, con el advenimiento del RTTI extendido (Delphi) y la reflexión (.Net y otros), no tengo reparos en usarlos junto con la anotación de los atributos del Modelo de Objetos de Negocios para poner todo en marcha y solo usar sobrecargas de, ganchos de código y / o clases de inicialización codificadas específicamente para cuidar el control de versiones de la base de datos.
Marjan Venema
5

Siendo realistas, MVC es principalmente un patrón de implementación de UI, por lo que la pregunta es algo discutible. Sin embargo, en realidad solo hay dos opciones de panorama general. Su controlador normalmente envía solicitudes para cargar o guardar entidades en su modelo utilizando 1) una capa de servicio de algún tipo o 2) el patrón de Registro Activo.

La capa de servicio puede adoptar cualquiera de varias formas, aunque mi preferencia personal es trabajar con una abstracción de repositorio para las entidades raíz agregadas, cuyas implementaciones concretas funcionarán con algún tipo de ORM, o un DAO liviano, o un API para alguna tienda no relacional si eso tiene sentido para la aplicación.

El patrón de registro activo significa que su modelo tiene la responsabilidad de la persistencia, aunque generalmente significa que una clase base de algún tipo administra las asignaciones a su tienda, por lo que su modelo no está realmente tan directamente involucrado.

Básicamente, el controlador envía solicitudes para persistir objetos, ya sea una llamada a su repositorio, su implementación de UnitOfWork o el método Save en sus entidades. Si está utilizando repositorios, sus objetos modelo ignoran la persistencia.

JasonTrue
fuente
3

En un sistema MVC (model-view-controller), el modelo contiene los datos. Así que creo que la persistencia de la base de datos debería estar en ella.

Nettogrof
fuente
2

La mayoría de las muestras de MVC de alto nivel que he visto tienen una infrastructurecapa separada que tiene el código de implementación de la base de datos real (es decir, las llamadas específicas a NHibernate, EF o Linq o lo que sea su capa de datos), mientras que la capa "modelo" (a menudo también la capa "Dominio") tiene las interfaces que definen los servicios de datos.

Wayne Molina
fuente
0

La práctica estándar en MVC es incluir la estructura de datos y la persistencia en la capa M (odel).

La capa del modelo no solo incluye las clases (POCO, etc.) que va a utilizar en su aplicación. Incluyen los repositorios para esas clases.

Un ejemplo sería un repositorio donde tiene grupos de instancias de clases de datos, es decir:

Clients repository

AllClients()
RecentClients()
ClientByID(int id)

Podrá organizar mejor su dominio de modelo y también tendrá acceso a sus datos de muchas maneras, pero aún así la capa de datos / modelo será compacta y robusta

Mihalis Bagos
fuente