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?
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:
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.
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.
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.
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.