web-dev-qa-db-fra.com

MVC: Où mettre la logique métier?

D'abord, j'ai vu beaucoup de questions à ce sujet, mais pas assez de raisonnement derrière cela. Si ma question n'est pas assez bonne et devrait être supprimée, je comprendrai.

Par exemple, j’ai jeté un coup d’œil à ceci et une réponse à voter de plus de 45 ans dit qu’il vous conseille de placer la logique d’entreprise dans le modèle, ce qui semble assez logique. 

Cependant, mon premier grand projet que j’ai réalisé avec tous mes BL dans les contrôleurs, car je n’ai pas remis en question ces éléments et j’ai examiné la procédure dans la AccountController qui est automatiquement ajoutée si vous choisissez MVC avec authentification par formulaire. Toutes les méthodes ont l'air bien farcies avec BL. Ou peut-être est-ce la moindre quantité de code qu'il était possible d'ajouter et je néglige des choses? 

Une personne sur youtube m'a demandé s'il avait raison en mettant toute la logique dans ses modèles et au début, j'étais non! Puis j'ai commencé à penser qu'il avait peut-être raison!? 

Alors, après tout, où dois-je placer ma logique métier? S'il s'agit de classes de modèles, quelle quantité de code doit-on considérer comme une quantité saine dans une méthode qui se trouve dans le contrôleur? Une ligne pour appeler une méthode du modèle dans un contrôleur au maximum, puis un retour à la vue?

62

Je préfère mettre la logique de domaine dans le modèle pour plusieurs raisons.

  1. Le modèle ne devrait pas contenir de code d'interface utilisateur et devrait donc être plus facile à tester. Autant que possible, j'aime bien avoir un modèle totalement fonctionnel (ce qui signifie une couverture de test complète) avant d'écrire un code d'interface utilisateur. Le contrôleur peut avoir confiance que le modèle agit correctement et s’occuper uniquement des problèmes d’assurance-chômage.

  2. Si vous mettez la logique de domaine dans un contrôleur, il n'est pas aussi facile de partager entre différentes applications, ni même entre différents contrôleurs.

46
Ferruccio

J'aime garder mes modèles propres I.e. Juste avec des propriétés et pas de logique métier. Je pense toujours qu'il est bon d'injecter des dépendances dans le contrôleur et que ces dépendances contiennent la logique que j'exécute sur mes modèles. J'aime adhérer au principe de responsabilité unique dans la mesure du possible et je trouve que les modèles avec des tonnes de méthodes sont gonflés très rapidement. Il y a des avantages et des inconvénients pour les deux. Injecter de nombreuses dépendances a un coût, mais permet de tester de manière isolée et de garder les classes simples et vous obtiendrez des contrôleurs plus simples. Malgré ma logique qui n'existe pas réellement sur mon modèle en tant que membre de la classe, sa logique reste la logique métier. J'ai tendance à ne pas définir la logique métier dans le contrôleur, car se moquer de choses comme le contexte HTTP est un peu un cauchemar et inutile.

36
Mark Walsh

La logique business appartient au domaine du problème et tout ce qui appartient au domaine du problème est renvoyé au modèle dans MVC.

Le contrôleur devrait être responsable de la transmission des données du modèle à la vue et de la vue au modèle. Le contrôleur constitue donc le pont entre les interactions de l'utilisateur et la manière dont le programme modélise et stocke l'état du problème. La plomberie , pour ainsi dire.

La clé ici est la distinction entre la logique métier et la logique de plomberie. À mon avis, le contrôleur de compte généré automatiquement consiste principalement à effectuer de la plomberie, et non pas une logique métier. N'oubliez pas que la logique de plomberie n'est pas forcément courte, vous n'avez donc pas besoin d'imposer de limites artificielles (comme "Nombre d'appels X au plus dans le contrôleur").

Lorsque mon équipe a déménagé de webforms (asp.net) vers mvc, elle a effectué beaucoup de recherches et a abouti à la structure suivante. Selon moi, l’application n’est pas grande ou petite. Il s’agit de garder le code propre et clair. 

DALProject

AccountsDAL.cs --- > Calls SP or any ORM if ur using any

BLLProject  

AccountsBLL.cs ---> Calls DAL

WebProject

Model
    AccountsModel --- > Contains properties And call BLL
Controllers
    IndexController ---> Calls Models and returns View
Views
    Index

Les contrôleurs devraient être responsables du transfert des données entre le modèle et la vue. En dehors de cela, il ne devrait pas y avoir de code inutile. Par exemple, si vous vous enregistrez, vous devez le faire au niveau du modèle plutôt que du contrôleur.

9
Muneeb Zulfiqar

Il semble y avoir une certaine confusion autour de ce sujet. La plupart du temps, il semble que les gens aient tendance à confondre le modèle MVC avec l’architecture N-tier en tant que situation ou situation. La réalité est que les deux approches peuvent être utilisées ensemble, mais l'une ne dépend pas de l'autre et aucune n'est requise. 

L'architecture à plusieurs niveaux vise à séparer une application en plusieurs niveaux. Un exemple simple est celui où l'application est divisée en une couche de présentation, une couche de logique métier et une couche d'accès aux données.

MVC est un modèle de conception traitant de la couche de présentation d'une application. Il est tout à fait possible de concevoir une application suivant une approche MVC sans séparer la logique d’entreprise et la logique d’accès aux données de la couche de présentation et aboutir ainsi à une conception à un seul niveau. 

Par conséquent, si vous suivez une approche MVC sans séparer également l'application en couches, vous vous retrouvez avec des modèles, des vues et des contrôleurs qui ont des éléments de règles de gestion et une logique d'accès aux données mélangés au reste de la logique. 

Par définition, dans une architecture à plusieurs niveaux, le niveau de présentation est supposé pouvoir uniquement communiquer avec la couche de logique métier. Il doit donc indiquer que l'un des composants MVC ne peut communiquer qu'avec la couche de logique métier.

Si vous construisez une application qui n'implique pas de présentation, et donc pas de couche de présentation, vous ne devriez pas avoir à vous préoccuper du motif MVC. Cependant, vous pouvez très bien diviser votre application en plusieurs niveaux et suivre ainsi une conception à plusieurs niveaux, même si aucune couche de présentation n'est impliquée.

8
treefiddy

De manière générale, la logique métier ne doit résider dans aucun des acteurs de MVC; il ne devrait être consommé que par les actions de votre contrôleur.

Comme beaucoup l'ont mentionné, il est préférable de créer une bibliothèque pour héberger la logique métier en tant qu'ensemble de composants réutilisables et autonomes pour le client.

De cette manière, nous augmentons considérablement la réutilisabilité, la compatibilité, l’évolutivité et la testabilité avec nos logiciels. Nous réduisons également notre dépendance à l'égard de certaines fonctionnalités de la structure, ce qui facilite la migration vers des technologies nouvelles/différentes.

La synthèse de notre logique commerciale en une ou plusieurs assemblées autonomes nous a bien servi au fil des ans. Notre logique métier peut alors être utilisée par pratiquement toutes les technologies .NET (ASP.NET MVC/API/Noyau, WPF, Formulaires Win, WCF, UWP, WF, Console, etc.).

En outre, nous souhaitons que notre niveau intermédiaire gère les règles métier et la logique de validation afin de réduire nos dépendances à l’égard du .NET MVC Framework. Par exemple, nous évitons d’utiliser les assistants de validation .NET MVCs et utilisons plutôt les nôtres. C'est un autre facteur qui nous permet de consommer facilement notre logique métier à partir de n'importe quelle technologie .NET.

En concevant logiquement notre niveau intermédiaire de cette manière, nous avons pu facilement réaliser cette architecture physique: 

 enter image description here

Il a été écrit avec Peasy.NET et nous a bien servi au fil des ans. Si bien en fait que nous avons décidé d'ouvrir le code source.

Si quelqu'un est curieux de savoir à quoi ressemble notre couche intermédiaire, voici un échantillon d'une couche métier agnostique pour le client. Il en présente également la consommation par plusieurs clients .NET (ASP.NET MVC, Web Api et WPF). 

J'espère que cela aide quelqu'un!

2
ahanusa

J'aime aussi garder mes modèles propres (réf: @Mark Walsh). Le problème de l'impossibilité de réutiliser la logique intégrée dans les contrôleurs peut facilement être résolu par injection de dépendances ou, si vous pensez que cela serait trop, exposez votre logique métier/domaine via des interfaces et utilisez le modèle de façade des contrôleurs. De cette façon, vous obtenez la fonctionnalité dont vous avez besoin, mais gardez les contrôleurs et le modèle propres et agréables.

2
Bob H

Comme l'a écrit ahanusa, vous devez placer les logiques de votre entreprise dans un répertoire DLL ou séparé.
J'utilise souvent un répertoire nommé Logics au même niveau que les modèles et les contrôleurs, où je mets des classes qui font de la logique métier.
.__ De cette façon, je laisse les modèles et les contrôleurs nettoyer. 

1
Ryozzo

Je préférerais aussi garder les modèles propres. Les contrôleurs MVC ne doivent être utilisés que pour passer des appels et doivent également rester propres. Donc, en fonction de sa réutilisabilité, de sa sensibilité et de sa pertinence, la logique métier peut être écrite en 

1. Contrôleur WebApi: / L’avantage d’utiliser un contrôleur webapi est que vous pouvez les exposer ultérieurement en tant que services à d’autres périphériques, ce qui rend votre code réutilisable.

2. BAL/Common commonent: Il y a certaines logiques qui ont un usage spécifique et qui ne peuvent pas être exposées en tant qu'API, peuvent être poussées dans cette classe.

3. Référentiel: Toutes les requêtes relatives à la base de données sont ajoutées dans un référentiel. Il peut y avoir un référentiel générique qui implémentera toutes les fonctions (opérations CRUD) ou des référentiels spécifiques pour chaque table. En fonction des opérations à effectuer.

1
Nikitesh

La réponse générale que j'ai est que la logique métier entre normalement dans deux catégories:

Logique métier orientée objet: Obtient la modélisation en tant qu'objets (dans le modèle), généralement injectés en tant que référentiels.

Procedure Business Logic: Se connecte à un service avec une interface pouvant être injectée dans un contrôleur.

Logique du contrôleur: Logique qui contrôle comment les commandes sont reçues et transmises aux modèles/services, puis comment ces résultats sont transmis à la vue.

Les contrôleurs ne doivent pas avoir de logique métier , c'est une partie très spécifique d'un modèle de conception pour contrôlant comment une interface utilisateur transmet les entrées aux modèles qui gèrent la logique métier (ou les services si vos problèmes sont de nature plus procédurale).

1
WhiteleyJ

Je sais que c'est une question à propos de MVC, mais je pense que l'exemple que je donne (API Web) sera utile.

Je développe ma première API Web et je réutilise la logique métier à partir d'autres applications. Pour être précis, il provient d'une DLL externe. Par conséquent, mon API est utilisée uniquement pour "discuter" avec une solution SAP, recevoir des demandes de la part de la commande d'achat et renvoyer des réponses.

Comment pourrais-je mettre ma logique (déjà implémentée) dans mon contrôleur? Je n'en ai pas besoin Mon contrôleur ne fera que recevoir, valider les demandes et composer les réponses pour renvoyer les données.

Je travaille avec les classes ViewModel et tout ce qu'elles doivent avoir est une fonction de mappage, il suffit de lire les informations de TransferObjects (qui provient de la DLL externe) et de les convertir en ViewModel.

Je ne suis pas à l'aise avec mon application (dans ce cas l'API Web) contenant la logique métier, je pense que la réutilisabilité sera perdue de cette manière. 

Je traite ma logique métier comme une dépendance que j'injecte dans le contrôleur.

J'ai beaucoup refactorisé l'héritage pour fournir une solution unitable, j'ai dû créer de nombreuses interfaces et implémenter des modèles de conception dans l'héritage pour fournir cette solution.

De mon point de vue, la couche de gestion doit être séparée de l'application, de préférence dans une autre bibliothèque de classes. Vous aurez donc un vrai concept de séparation implémenté dans votre application.

Bien entendu, si votre CORE (entreprise) est votre application (API/WebSite) , les règles commerciales seront implémentées dans vos classes MVC. Mais à l'avenir, si vous souhaitez développer une nouvelle application et que certaines règles commerciales sont identiques, je parie que vous aurez beaucoup de problèmes simplement pour maintenir la même logique mise en œuvre dans les deux applications.

0
Otta Augusto