web-dev-qa-db-fra.com

Pourquoi mettre la logique métier dans le modèle? Que se passe-t-il lorsque j'ai plusieurs types de stockage?

J'ai toujours pensé que la logique métier doit être dans le contrôleur et que le contrôleur, puisqu'il s'agit de la partie "centrale", reste statique et que le modèle/vue doit être capsulé via des interfaces. De cette façon, vous pouvez changer la logique métier sans affecter quoi que ce soit d'autre, programmer plusieurs modèles (un pour chaque base de données/type de stockage) et des dizaines de vues (pour différentes plates-formes par exemple).

Maintenant, je lis dans cette question que vous devez toujours mettre la logique métier dans le modèle et que le contrôleur est profondément connecté à la vue.

Pour moi, cela n'a pas vraiment de sens et implique que chaque fois que je veux avoir les moyens de prendre en charge une autre base de données/type de stockage, je dois réécrire tout mon modèle, y compris la logique métier.

Et si je veux une autre vue, je dois réécrire la vue et le contrôleur.

Quelqu'un peut-il expliquer pourquoi c'est ou si je me suis trompé quelque part?

71
Steffen Winkler

la réponse d'ElYusubov le cloue le plus souvent, la logique du domaine devrait aller dans le modèle et la logique d'application dans le contrôleur.

Deux clarifications:

  • Le terme logique métier est ici plutôt inutile, car il est ambigu. La logique métier est un terme générique pour toute logique qui intéresse les hommes d'affaires, la séparant des simples détails techniques comme la façon de stocker des éléments dans une base de données ou de les afficher sur un écran. La logique de domaine ("une adresse e-mail valide ressemble à ...") et les flux de travail/processus métier ("lorsqu'un utilisateur s'inscrit, demande son adresse e-mail") sont considérés comme une logique métier, la première appartenant clairement au modèle et ce dernier étant la logique d'application qui va dans le contrôleur.
  • MVC est un modèle pour mettre des choses sur un écran et permettre à l'utilisateur d'interagir avec lui, il ne spécifie pas du tout le stockage . La plupart des frameworks MVC sont des frameworks à pile complète qui vont au-delà du simple MVC et vous aident à stocker vos données, et parce que les données qui doivent être stockées se trouvent généralement dans le modèle, ces frameworks vous offrent des moyens pratiques de stocker votre modèle. données dans une base de données, mais cela n'a rien à voir avec MVC. Idéalement, les modèles devraient être indépendants de la persistance et le passage à un autre type de stockage ne devrait pas du tout affecter le code du modèle. Les architectures à part entière ont une couche de persistance pour gérer cela.
71
Waquo

Vous et de grandes parties du monde de la programmation semblez mal comprendre quels sont les rôles des parties MVC. En bref, ce sont:

Modèle = logique du domaine

Voir = logique de sortie

Contrôleur = logique d'entrée

Cela signifie que le modèle est responsable de toute la logique métier: tout ce qui est lié au dessin de widgets sur un écran, au pilotage d'une imprimante, à la sortie de données au format HTML, à l'analyse des requêtes HTTP, etc., etc. n'appartient pas au modèle.

Cependant, la plupart des frameworks dits "MVC" modernes ne font pas vraiment du tout MVC, ou ils étiquettent mal leurs pièces. Très souvent, ce qu'on appelle le "modèle" est la couche de persistance du modèle, tandis que la logique métier se trouve dans ce qu'ils appellent le "contrôleur"; le contrôleur réel n'est généralement qu'un point d'entrée central avec une table de routage et un peu de code dans les "contrôleurs" individuels pour envoyer les informations reçues aux processus métier appropriés. Ce que ces frameworks appellent "vue" est vraiment un peu de tout: une logique de présentation (View), un peu de gestion et de validation des entrées (Controller), et encore plus de logique métier (Model). La part du lion de la vue réelle est généralement appelée "modèles".

Vous voudrez peut-être également en savoir plus sur l'architecture à plusieurs niveaux; où MVC est un peu à sens unique (le flux est Controller -> Model -> View), Multi-Tier est une chose à double sens (Présentation -> Logique -> Données -> Logique -> Présentation), et quelques-uns les cadres qui prétendent faire MVC font en fait trois niveaux, en réétiquetant la présentation à la vue, la logique au contrôleur et les données au modèle.

24
tdammers

Pour vraiment isoler la logique métier et la séparer de l'infrastructure de la couche de présentation, elle doit être encapsulée par les services d'application. L'architecture MVC est un moyen d'implémenter la couche de présentation et elle doit rester dans cette portée, en déléguant toute la logique métier à ces services d'application. Considérez les modèles de vue comme des adaptateurs entre la vue et les données qui doivent être affichées ou lues. Le contrôleur sert d'intermédiaire entre les modèles de vue, les vues et les services d'application qui hébergent la logique métier.

Les services d'application implémentent des cas d'utilisation métier et sont découplés de la couche de présentation, que ce soit MVC ou autre. À leur tour, les services d'application peuvent héberger scripts de transaction ou conception pilotée par domaine .

Pour le stockage, le service d'application peut référencer un référentiel ou toute abstraction d'un mécanisme de persistance. Différentes implémentations peuvent être prises en charge en faisant abstraction de l'accès aux données dans une interface. En règle générale, ces abstractions sont fuite et ne sont que partiellement portables sur plusieurs implémentations et il s'agit souvent d'une tentative futile d'atteindre la pleine portabilité.

[~ # ~] mise à jour [~ # ~]

Ma suggestion est basée sur Architecture hexagonale . Dans une architecture hexagonale, votre modèle de domaine (logique métier) est au cœur. Ce cœur est encapsulé par des services d'application qui agissent comme façade . Les services d'application sont des classes simples qui ont des méthodes correspondant aux cas d'utilisation de votre domaine. Pour une discussion approfondie sur les services d'application, consultez Services in Domain-Driven Design . L'exemple de code contient un PurchaseOrderService qui est un service d'application pour un domaine d'achat. (Notez qu'un service d'application n'implique pas l'utilisation d'une conception pilotée par domaine.)

Dans une architecture hexagonale, une couche de présentation MVC est un adaptateur entre votre modèle de domaine (logique métier) et une interface graphique. Le modèle de domaine ne connaît pas la couche de présentation, mais la couche de présentation connaît le modèle de domaine.

Cette solution a certainement des pièces mobiles qu'une solution qui place la logique métier dans le contrôleur et vous devriez peser les inconvénients et les avantages. La raison pour laquelle je le suggère est que je préfère garder la logique métier découplée de la couche de présentation afin de lutter contre la complexité. Cela devient plus important à mesure que l'application se développe.

15
eulerfx

Cela dépend de ce que vous entendez par logique métier. Toute "logique" qui donne un sens au contenu du modèle doit être dans le modèle. Dans la question liée, la réponse la plus votée semble définir la "logique métier" comme tout ce qui concerne les données; cela a du sens du point de vue que les données d'une entreprise sont ses affaires!

J'ai vu un exemple par le créateur de Rails (je pense) qui se passait exactement à ce sujet - sans mettre de "logique métier" dans le modèle. Son exemple était une classe de contrôleur et une méthode pour inscription et connexion à l'application - un mot de passe fourni en texte brut a été chiffré avant d'être inséré ou interrogé par rapport au modèle (une base de données.)

Je ne peux pas penser à un meilleur exemple de quelque chose qui n'est pas une logique de contrôleur et qui appartient directement au modèle.

Le modèle pourrait être une interface avec une myriade de magasins de données, atténuant les problèmes de portabilité. C'est ici que l'on pourrait trouver de la confusion quant à savoir si l'interface du modèle est en fait le "contrôleur".

De manière générale, le contrôleur relie le modèle et la vue (qui sont les viandes et les pommes de terre de l'application.) Dans le développement de Cocoa, il peut être simpliste au point où le contrôleur est géré via l'interface graphique XCode (objets et liaisons du contrôleur).

La section "Design Patterns" du GoF sur MVC, citée de manière lâche:

La triade de classes MVC est utilisée pour créer des interfaces utilisateur dans Smalltalk-80. Le modèle est l'objet d'application, la vue est sa présentation d'écran et le contrôleur définit la façon dont l'interface utilisateur réagit aux entrées de l'utilisateur. MVC dissocie les vues et les modèles en établissant un protocole d'abonnement/notification entre eux. Le diagramme suivant montre un modèle et trois vues. Nous avons laissé de côté les contrôleurs pour plus de simplicité.

MVC est tout au sujet des interfaces utilisateur. L'accent est mis sur le modèle et la vue - définissant et affichant les données. Notez le "protocole d'abonnement/notification" - c'est là que votre contrôleur entre en jeu. Vous pouvez créer toutes les vues que vous voulez; tant qu'ils adhèrent au protocole, vous n'aurez jamais à toucher le modèle ou le contrôleur.

Si vous parlez de développement Web en particulier, à mon humble avis, de nombreux cadres Web populaires sont rapides et lâches avec le terme MVC et ses définitions de composants.

1
Duke

Pourquoi n'introduisez-vous pas une couche de service?

Ensuite, votre contrôleur sera maigre et plus lisible, puis toutes vos fonctions de contrôleur seront de pures actions.

Vous pouvez décomposer la logique métier autant que vous le souhaitez dans la couche de service. La réutilisation du code est meilleure et il n'y a aucun impact sur les modèles et les référentiels.

0
Anil