Lors de la planification de l'architecture d'une application Web MVC à moyenne et grande échelle, comment implémentez-vous les couches pour qu'elles soient aussi découplées que possible et faciles à tester? (suivez essentiellement les meilleures pratiques) Supposons que j'utilise d'abord le code comme accès aux données.
J'ai du mal à définir la "logique métier" et comment elle doit interagir avec la couche de données. En prenant une application de vente de véhicules comme exemple, la logique commerciale serait-elle des classes qui effectuaient des tâches telles que le calcul de la fourchette de taxe pour des véhicules donnés, la comparaison de statistiques de mile par gallon, etc.? Quant aux entités commerciales (par exemple les voitures, les fourgonnettes, les motos), je les mettrais dans la couche de données avec ma DataContext
classe.
De plus, qu'est-ce qui constituerait une logique d'application par opposition à une entreprise - je suppose des choses comme des validations d'entrée de session / utilisateur?
Ainsi, par exemple, un contrôleur de voiture peut retourner un résultat d'action / vue qui répertorie les dix meilleures voitures filtrées par type et meilleur mpg. Alors disons que j'ai un ICarRepository
'carRepo' injecté dans mon contrôleur (en utilisant le modèle de référentiel / DI), je filtre mes voitures à partir d'un paramètre de méthode d'action, par exemplevar cars = carRepo.getCarsByType("hatchback");
J'ai donc gardé les connaissances d'accès aux données hors de mon contrôleur en utilisant un référentiel, maintenant pour garder la logique métier hors du contrôleur en utilisant un modèle de domaine - var result = new MpgCalculator (cars); - Disons que j'ai besoin de la classe de calculatrice car elle doit effectuer une logique supplémentaire pour calculer la meilleure efficacité énergétique, plus que simplement charger / filtrer des entités à partir de la base de données. Alors maintenant, j'ai un ensemble de données à afficher pour ma vue qui utilise un référentiel pour récupérer à partir de la couche d'accès aux données, et un objet spécifique au domaine pour traiter et effectuer des tâches liées à l'entreprise sur ces données.
Suis-je en train de faire des erreurs ici? avons-nous encore besoin d'utiliser le modèle de référentiel ou puis-je simplement coder contre une interface pour découpler l'ORM et tester? À ce sujet, comme mes classes concrètes d'accès aux données dbcontext sont dans la couche de données, les définitions d'interface doivent-elles aller dans la couche domaine / entreprise, ce qui signifie que si la technologie d'accès aux données est modifiée, mes autres couches ne sont pas affectées?
D'après ce que j'ai étudié jusqu'à présent, ma structure ressemble à ceci:
Application Internet MVC -> Le projet Internet standard - les modèles ici sont ViewModels
Couche domaine / entreprise -> classes / modèles spécifiques à l'entreprise que les contrôleurs peuvent utiliser pour traiter les entités de domaine de la couche de données avant de passer aux vues pertinentes
Abstraction du référentiel nécessaire? -> J'entends beaucoup de débats à ce sujet, en particulier lors de l'utilisation d'un ORM
Couche de données -> Classes d'entité (voiture, fourgonnette, moto), DbContext - Couche de technologie d'accès aux données concrètes
la source
Il semble que tout soit correct pour votre structure. La seule chose dont je ne suis pas sûr, c'est que vous mentionnez que les modèles dans MVC sont des "ViewModels" et que vos contrôleurs parlent à la couche domaine. Je pense que cela a du sens si votre modèle par défaut consiste à utiliser le contrôleur pour accéder à la couche de domaine, puis à utiliser vos "ViewModels" comme compilations d'informations plus spécifiques à la vue à partir de plusieurs entités de domaine, comme il est logique pour cette vue particulière. Si c'est ce que vous faites, vous êtes probablement d'accord.
Il existe une école de pensée selon laquelle vous devriez avoir une abstraction complète de votre couche de domaine dans votre application MVC si vous en avez. Personnellement, l'idée de faire cela dans une application d'entreprise me cause de graves douleurs mentales.
Je préfère utiliser le modèle de référentiel pour gérer l'accès à la couche de données car il améliore la testabilité et la flexibilité. L'interface utilisateur et la base de données sont les deux choses qui ont tendance à apporter les changements les plus drastiques. Imaginez si certaines des informations que vous extrayez directement de la base de données sont modifiées de sorte qu'elles doivent être récupérées à partir d'un appel de service plutôt que d'un appel à la base de données, ou si certaines informations sont déplacées vers une autre base de données nécessitant un .edmx différent fichier. Le modèle de référentiel fournit une abstraction pour prendre en charge cela.
la source