Dans un système MVC, où doit se situer le code de persistance de la base de données?

21

J'ai vu plusieurs configurations pour la persistance d'informations dans la base de données. Généralement, trois types de designs semblent communs dans mon coin du monde:

  • Le contrôleur gère la persistance
  • Le modèle gère la persistance
  • La bibliothèque tierce gère la persistance, nécessitant généralement une sorte d'annotations sur le modèle.

Je me demande quelle configuration (le cas échéant) est, conceptuellement, la plus facile à utiliser / la plus compatible avec une architecture MVC?

(Si ce n'est pas un que j'ai énuméré, veuillez donner un bref aperçu / aperçu dans le cadre de la réponse)

blueberryfields
la source

Réponses:

13

Vos deuxième et troisième options sont identiques. Le M dans MVC n'est pas le modèle de données, mais plutôt le modèle de domaine. Cela inclut la persistance, que ce soit fait directement ou via un ORM, et les deux sont parfaitement corrects.

Le contrôleur doit gérer le flux du site et transmet les éléments au domaine (parfois via une couche de service) pour les manipuler, de sorte que la persistance à partir de là est incorrecte - ou du moins sémantiquement inconfortable.

pdr
la source
2
Je suis en désaccord dans une certaine mesure. L'utilisation concrète de la persistance est une logique d'application et appartient donc à une couche application et non à la couche domaine. La couche de domaine (contenant le modèle de domaine) ne doit pas tenir compte de la persistance du programme commercial occasionnel. Le contrôleur est un orchestrateur . Il peut orchestrer les services (de données), l'interface utilisateur et le modèle de domaine.
Falcon
1
@Falcon: Alors que le contrôleur doit contrôler le moment où les données sont chargées et persistées dans la base de données, il est tout à fait correct de lui demander de le faire. L'utilisation d'un ORM (standard ou roll-your-own) signifie généralement dire au modèle de charger / enregistrer qui délègue ensuite à l'ORM. Une autre façon pourrait être de demander au contrôleur de dire à un ORM de charger / enregistrer quelque chose en lui passant une classe de modèle à charger (avec des critères de sélection) ou une instance de modèle à enregistrer. Dans les deux cas, le chargement / enregistrement réel sera intimement lié au modèle.
Marjan Venema
@Marjan Venema: Oui, je suis d'accord, mais la question est de savoir où ce code devrait vivre. Je m'efforce de garder le modèle aussi ignorant que possible de la persistance et de modéliser uniquement les entités du domaine avec leurs comportements et interactions. Tout le reste vivra dans les couches d'application (car c'est une application de mon modèle). Le mappage des informations / accès aux données est complètement découplé du modèle de domaine et peut également prendre en charge la gestion des versions (mise à niveau / rétrogradation). L'application de l'accès aux données vit également dans les couches d'application (qui contiennent des services, des référentiels, etc.)
Falcon
@ Falcon: Oui, c'est une bonne façon de le faire et c'est ainsi que je l'ai fait dans le passé en utilisant des classes de mappage distinctes. Cependant, avec l'avènement du RTTI étendu (Delphi) et de la réflexion (.Net et autres), je n'ai aucun scrupule à les utiliser en conjonction avec l'annotation des attributs du modèle d'objet métier pour tout faire fonctionner et utiliser simplement des surcharges de, des crochets de code dans et / ou des classes d'initialisation spécifiquement codées pour prendre en charge la gestion des versions de la base de données.
Marjan Venema
5

De façon réaliste, MVC est principalement un modèle d'implémentation d'interface utilisateur, donc la question est quelque peu théorique. Cependant, il n'y a vraiment que deux options à grande échelle. Votre contrôleur envoie généralement des demandes de chargement ou d'enregistrement d'entités dans votre modèle en utilisant 1) une couche de service quelconque ou 2) le modèle d'enregistrement actif.

La couche de service peut prendre plusieurs formes, bien que ma préférence personnelle soit de travailler avec une abstraction de référentiel pour les entités racine agrégées, dont les implémentations concrètes fonctionneront soit avec une sorte d'ORM, soit un DAO léger, soit un API pour un magasin non relationnel si cela a du sens pour l'application.

Le modèle d'enregistrement actif signifie que votre modèle est responsable de la persistance, bien que cela signifie généralement qu'une classe de base quelconque gère les mappages vers votre magasin, de sorte que votre modèle n'est pas vraiment directement impliqué.

Fondamentalement, le contrôleur envoie des demandes de persistance d'objets, qu'il s'agisse d'un appel à votre référentiel, à votre implémentation UnitOfWork ou à la méthode Save sur vos entités. Si vous utilisez des référentiels, vos objets de modèle ignorent la persistance.

JasonTrue
la source
3

Dans un système MVC (model-view-controller), le modèle contient les données. Je pense donc que la persistance de la base de données devrait y figurer.

Nettogrof
la source
2

La plupart des échantillons MVC de haut niveau que j'ai vus ont une infrastructurecouche distincte qui a le code d'implémentation de la base de données réelle (c'est-à-dire les appels spécifiques à NHibernate, ou EF ou Linq ou quelque soit votre couche de données), tandis que la couche "modèle" (souvent aussi la couche "Domaine") possède les interfaces qui définissent les services de données.

Wayne Molina
la source
0

La pratique standard dans MVC est d'inclure la structure et la persistance des données dans la couche M (odel).

La couche modèle n'inclut pas seulement les classes (POCO, etc.) que vous allez utiliser dans votre application. Ils incluent les référentiels de ces classes.

Un exemple serait un référentiel où vous avez des groupes d'instances de classes de données, c'est-à-dire:

Clients repository

AllClients()
RecentClients()
ClientByID(int id)

Vous pourrez mieux organiser votre domaine de modèle et aurez également accès à vos données de nombreuses façons, mais la couche données / modèle sera toujours compacte et robuste

Mihalis Bagos
la source