Les gros modèles et les contrôleurs maigres ressemblent à la création de modèles de Dieu [fermé]

91

J'ai lu beaucoup de blogs qui prônent l' approche des gros modèles et des contrôleurs maigres , en particulier. le camp des Rails. En conséquence, les routeurs déterminent simplement quelle méthode appeler sur quel contrôleur et tout ce que la méthode du contrôleur fait est d'appeler la méthode correspondante sur le modèle, puis d'afficher la vue. J'ai donc ici deux préoccupations que je ne comprends pas:

  1. Le contrôleur et le routeur ne font vraiment pas des tâches très différentes, à part simplement appeler une méthode sur le modèle divin basé sur l'itinéraire.
  2. Les modèles en font trop. Envoi de courriels, création de relations, suppression et modification d'autres modèles, mise en file d'attente de tâches, etc. Fondamentalement, vous avez maintenant des objets divins qui sont censés faire tout ce qui peut ou non concerner la modélisation et le traitement des données.

Où tracez-vous la ligne? N'est-ce pas simplement tomber dans le modèle de Dieu?

Chasseur de la jungle
la source

Réponses:

136

Ce n'est peut-être pas la meilleure idée de considérer les rails comme un élément de base du modèle de conception MVC. Ledit cadre a été créé avec quelques lacunes inhérentes (je l'ai un peu développé dans un article différent ) et la communauté vient de commencer à s'attaquer aux retombées. Vous pouvez considérer le développement de DataMapper2 comme la première étape majeure.

Une théorie

Les personnes qui donnent ce conseil semblent être affligées par une idée fausse assez courante. Alors laissez-moi commencer par clarifier les choses: le modèle, dans le modèle de conception MVC moderne, n'est PAS une classe ou un objet. Le modèle est une couche.

L'idée principale derrière le modèle MVC est la séparation des préoccupations et la première étape est la division entre la couche de présentation et les couches de modèle. Tout comme la couche de présentation se décompose en contrôleurs (instances, responsables de la gestion des entrées utilisateur), vues (instances, responsables de la logique de l'interface utilisateur) et modèles / mises en page, la couche de modèle en fait autant.

Les principaux composants de la couche de modèle sont les suivants:

  • Objets de domaine

    Également connu sous le nom d'entités de domaine, d'objets métier ou d'objets de modèle (je n'aime pas ce dernier nom car il ne fait qu'ajouter à la confusion). Ces structures sont ce que les gens appellent à tort des «modèles». Ils sont responsables de contenir les règles métier (toutes les mathématiques et la validation pour une unité spécifique de la logique de domaine).

  • Abstractions de stockage:

    Habituellement implémenté à l'aide d' un modèle de mappeur de données (ne pas confondre avec les ORM , qui ont abusé de ce nom). Ces instances sont généralement chargées du stockage et de la récupération des informations dans les objets du domaine. Chaque objet de domaine peut avoir plusieurs mappeurs, tout comme il existe plusieurs formes de stockage (DB, cache, session, cookies, / dev / null).

  • Prestations de service:

    Structures responsables de la logique d'application (c'est-à-dire interaction entre les objets du domaine et interaction entre les objets du domaine et les abstractions de stockage). Ils doivent agir comme "l'interface" à travers laquelle la couche de présentation interagit avec la couche modèle. C'est généralement ce qui se retrouve dans le code de type Rails dans les contrôleurs.

Il existe également plusieurs structures qui peuvent se trouver dans les espaces entre ces groupes: les DAO , les unités de travail et les référentiels .

Oh ... et quand on parle (dans le contexte du web) d'un utilisateur qui interagit avec l'application MVC, ce n'est pas un être humain. L '«utilisateur» est en fait votre navigateur Web.

Alors qu'en est-il des divinités?

Au lieu d'avoir un modèle effrayant et monolithique avec lequel travailler, les contrôleurs devraient interagir avec les services. Vous transmettez les données de l'entrée utilisateur à un service spécifique (par exemple MailServiceou RecognitionService). De cette façon, le contrôleur change l'état de la couche de modèle, mais cela se fait en utilisant une API claire et sans jouer avec les structures internes (ce qui provoquerait une abstraction qui fuit).

De telles modifications peuvent provoquer une réaction immédiate ou affecter uniquement les données que l'instance de vue demande à la couche de modèle, ou les deux.

Chaque service peut interagir avec n'importe quel nombre (cependant, ce n'est généralement qu'une poignée) d'objets de domaine et d'abstractions de stockage. Par exemple, le RecogitionServicene se soucie pas moins des abstractions de stockage pour les articles.

Notes de clôture

De cette façon, vous obtenez une application qui peut être testée unitaire à n'importe quel niveau, a un faible couplage (si elle est correctement mise en œuvre) et une architecture clairement compréhensible.

Cependant, gardez à l'esprit: MVC n'est pas destiné aux petites applications. Si vous écrivez une page de livre d'or en utilisant le modèle MVC, vous le faites mal. Ce modèle est destiné à faire respecter la loi et l'ordre dans les applications à grande échelle.

Pour les personnes qui utilisent PHP comme langue principale, cet article pourrait être pertinent. C'est une description un peu plus longue de la couche de modèle avec quelques extraits de code.

tereško
la source
Réponse très utile et complète! Connaissez-vous un livre qui explique un peu plus le modèle architectural MVC? Surtout sur la partie des modèles que tout le monde pense à tort "Le modèle représente les données et ne fait rien d'autre." et cela ressemble plus à l'idée d'objet de domaine, pas au «modèle» -> tomdalling.com/blog/software-design/…
thermz
1
@thermz, afaik , il n'y a vraiment pas de livres qui traitent exclusivement du modèle MVC. En général, je dis simplement aux gens de lire PoEAA , puis de creuser. Peut-être que cette liste de liens pourrait être utile. Je trouve que, lorsque les gens ont une solide compréhension des principes et des concepts de la POO, le modèle devient assez facile à comprendre.
tereško
@ tereško belle réponse. Hibernate y parvient-il? Je ne suis pas convaincu par les réponses ici -> stackoverflow.com/questions/1308096/…
Ankan-Zerob
@ Ankan-Zerob comme vous le remarquerez peut-être, je ne suis pas un développeur Java, mais d'après ce que je sais sur Hibernate, il fournit un ensemble d'outils complet pour la couche de persistance. Cela vous donnera une partie de ce qui y est décrit, mais pas une couche de modèle complète.
tereško
3
@johnny pas pour autant que je sache. La plupart des soi-disant "frameworks mvc" de php sont des variantes de Rails. Et, dans le cadre du cours, la plupart d'entre eux sont livrés avec des solutions ORM actives basées sur les enregistrements (ces éléments sont notoirement fragiles aux changements de base de données). Vous pouvez implémenter quelque chose comme ça avec SF2.x ou ZF2.x, mais le but d'un framework n'est pas d'implémenter / appliquer une architecture spécifique mais de fournir des outils. De plus, en ce qui concerne MVC, il est implémenté par le code de l'application et non par le framework.
tereško le
5

Si les classes «modèle» sont mal implémentées oui, votre préoccupation est pertinente. Une classe de modèle ne devrait pas faire de courrier électronique (tâches d'infrastructure).

La vraie question est ce qu'implique le modèle dans MVC. Il n'est pas limité aux classes POCO avec quelques méthodes. Le modèle dans MVC signifie les données et la logique métier. Traitez-le comme un sur-ensemble de modèles POCO classiques.

Afficher ==== Controller ==== Model ---> Couche de processus métier -> Modèles de base

Ajoutez des assemblys d'infrastructure et des couches d'accès aux données et utilisez l'injection pour transférer cela dans le BPL, puis votre processus utilise MVC comme prévu.

BPL peut invoquer des modèles UoW / Respository, et exécuter des règles métier et appeler des fonctionnalités d'infrastructure au moyen d'objets injectés ou de modèles d'interface.

Ainsi, la recommandation de garder un contrôleur maigre ne signifie pas que la classe "personne" dans un modèle Core classique devrait avoir 50 méthodes et appeler directement Email. Vous avez raison de penser que c'est faux.

Le contrôleur peut encore être obligé d'instancier et d'injecter des classes d'infrastructure dans le BPL ou la couche principale s'il est appelé directement. Il doit y avoir une couche de gestion ou au moins des classes orchestrant les appels entre les classes de modèle d'objet classique. Et bien c'est ma "vue" quand même ;-)

Pour une version générique de MVC, la description du wiki http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Un petit blog qui parle du "M" dans MVC. http://www.thedeveloperday.com/skinny-controllers/

phil soady
la source
1
Si vous n'êtes pas d'accord, soyez au moins suffisamment courtois pour justifier votre point de vue
phil soady
-1

Je pense que vous pouvez faire une distinction entre un seul gros modèle (éventuellement nommé App ou Application), et plusieurs gros modèles répartis en groupes logiques (Business, Customer, Order, Message). Ce dernier est la façon dont je structure mes applications, et chaque modèle correspond à peu près à une table de base de données dans une base de données relationnelle ou une collection dans une base de données de documents. Ces modèles gèrent tous les aspects de la création, de la mise à jour et de la manipulation des données qui composent le modèle, qu'il s'agisse de communiquer avec la base de données ou d'appeler une API. Le contrôleur est très mince responsable de peu plus que d'appeler le modèle approprié et de sélectionner un modèle.

Bryan Young
la source