Une vue et un modèle doivent-ils communiquer ou non?
33
Selon la page wikipedia de l’architecture MVC , la vue est libre d’être notifiée par le modèle et d’interroger le modèle sur son état actuel. Cependant, selon le cours de Paul Hegarty sur iOS 5 à Stanford, conférence 1, page 18, toute interaction doit passer par le contrôleur, avec Model et View qui ne sont jamais supposés se connaître. Il n’est pas clair pour moi si la déclaration de Hegarty doit être conçue comme une simplification du cours, mais je suis tenté de dire qu’il a l'intention de concevoir le projet en tant que tel.
Comment expliquez-vous ces deux points de vue opposés?
C'est un sujet controversé dans MVC / MVVM. Certains disent qu'il est correct que la vue accède aux modèles directement, d'autres disent que vous devez envelopper les modèles dans ViewModels afin de les soustraire à la vue. Personnellement, je ne suis pas fan de l'une ou l'autre approche.
L'un des principaux objectifs de MVC / MVVM est de découpler l'interface utilisateur, la logique métier et les données. En gardant ce concept à l'esprit, le fait de permettre à la vue d'accéder directement aux modèles crée une dépendance que vous ne souhaitez peut-être pas avoir. D'un autre côté, emballer les modèles dans ViewModels est souvent fastidieux et peu utile car les ViewModels ont tendance à servir simplement de passerelle aux modèles.
J'aime l'approche consistant à faire en sorte que vos modèles implémentent une interface particulière, appelons-la IModel. Votre classe ViewModel peut ensuite proposer des instances d'objets qui implémentent la consommation IModel for View. View sait simplement que cela fonctionne avec les objets IModel qu'il obtient du ViewModel. Cela supprime le code wrapper ViewModel superflue ainsi que la mise en œuvre concrète d'IModel à partir de la vue. Vous pouvez ultérieurement échanger une implémentation d'IModel contre une autre sans affecter la vue d'un bit.
En ce qui concerne les aspects fastidieux de la cartographie d'un modèle à un modèle de vue, il convient de noter qu'il existe des outils disponibles qui peuvent faciliter la cartographie. EG: (.NET AutoMapper) (JAVA modelmapper)
Jesse
+1 excellente réponse! C'est une excellente approche en fonction de la complexité de votre modèle, mais la plupart des modèles actuels sont du type Anemic. type . Les éléments du modèle étant un peu plus que des objets de données sans comportement, je ne vois pas la nécessité d'une telle abstraction et présente peu de danger en permettant à votre vue d'accéder directement à votre modèle.
maple_shaft
2
J'entends ce que tu dis; la plupart des interfaces IModel contiennent simplement un ensemble de déclarations de propriétés et peu (le cas échéant) de déclarations de méthodes. Mais même si les modèles sont anémiques, l'interface dissocie toujours la vue de sa mise en œuvre concrète. Cette séparation peut ne pas être nécessaire pour chaque projet, mais il est toujours judicieux de laisser les options ouvertes.
Raymond Saltrelli
1
Je suis confus, si vous avez un ensemble de points de vue absolument différents, comment pouvez-vous vous fier à une interface sans l'encombrer? Je pense que les modèles de vue sont fantastiques. Vous créez des modèles assez génériques pour pouvoir être utilisés dans votre application et vous créez des modèles de vue pour qu'ils consomment un ou plusieurs modèles et implémentent en outre des opérations qui ne seraient utilisées que par cette vue.
Le muffin homme
12
Sur le Web, tout le monde appelle son découplage MVC.
Certaines technologies, telles que C #, utilisent MVVM car il n’existe aucun lien entre la vue et une autre, tout passe par le localisateur de service et lie les variables.
Sur le MVC pur, la vue communique directement avec le modèle et inversement. Le contrôleur n’est présent qu’en cas de changement.
Et puis, il y a celui appelé PAC (Presentation Abstraction Control). Dans cette architecture, la vue et le modèle ne se parlent pas. Le contrôleur est le seul autorisé à faire quoi que ce soit avec la vue ou le modèle. Les gens confondent souvent cela avec MVC.
Pour moi, l’objectif fondamental d’une architecture est de ne pas entraver les futures tentatives de refactorisation. En règle générale, les vues qui interagissent directement avec les modèles répondent à cette exigence et il est relativement clair que ce n'est pas le cas.
Quand une vue devient trop intime avec un modèle, un ViewModel peut être une belle chose, mais c'est généralement le cas pour moi que les cas où elle est appelée sont minoritaires.
En MVC , Paul Hegarty a tort. Le contrôleur concerne les événements utilisateur, pas la communication modèle-vue. En MVC classique , la ou les vues observent le modèle (motif Observer).
Avec le gars entre la médiation, le modèle devrait être appelé MVP . En fait, la plupart de ce que l'on présente aujourd'hui comme MVC est en réalité plus proche de MVP.
Ensuite, il y a MVVM, qui est quelque chose de similaire aux deux, et pourtant un peu différent, qui existait il y a longtemps ... il est préférable de le voir comme deux MVC / MVP liés ensemble par un objet viewmodel - le "client" MVC a viewmodel son modèle, et le "serveur" MVC a le viewmodel comme vue.
Aujourd'hui (début 2014), pour moi (avec mon nœud et ma pile angulaire) cette distinction entre MVC "client" et MVC "serveur" semble très pertinente et en quelque sorte éclairante. (merci)
slacktracer
4
Puisque vous posez des questions sur le contenu de ces conférences à Stanford en particulier, il convient de considérer deux aspects de la position de Hegarty:
Comme vous l'avez dit, il enseigne un cours de science informatique de niveau 100. Dans ses cours, il y a de nombreux endroits où il simplifie, passe au-dessus des détails ou dit «faites-le comme ça», comme il est probablement nécessaire de le faire pour enseigner les bases, c'est-à-dire que vous devez maîtriser les règles avant de pouvoir les enfreindre.
Mon expérience avec le SDK iOS est que, où il n'a pas appliquer une séparation stricte entre vue et le modèle, il est orienté fortement vers ce modèle. Lors de l'écriture d'applications iOS en particulier, le respect de la séparation modèle-vue vous permet d'écrire un code conforme aux attentes du framework. J'hésiterais à généraliser les déclarations de Hegarty au développement sur d'autres plates-formes ou en général.
Je suis d'accord avec Paul Hegarty et pense que la vue ne doit pas connaître le modèle. Ce n'est pas si difficile à réaliser, mais cela apporte des avantages supplémentaires à votre conception et à votre flexibilité future.
Dans les petites applications (généralement de bureau) où je voudrais éviter les classes ViewModel "factices" et garder les choses simples, j'utilise également l'interface IModel (voir la réponse ci-dessus) et veille à ce que Model n'ait aucune idée de la vue (utiliser les abonnés comme dans le MVC classique).
De plus, dans ce cas, le contrôleur est associé à la vue et par souci de simplicité, je ne les sépare pas toujours clairement.
La deuxième approche «simplifiée» convient si vous pouvez avoir plusieurs vues pour le même modèle, mais je ne le recommanderais pas si vous souhaitez utiliser la même vue pour différents modèles. Par différent, je veux dire très différent par nature et pas seulement par les classes de test JUnit qui "suivent" le modèle principal.
Je crois qu'il n'y a pas de règle absolue pour cela, cela dépend totalement de vos besoins.
Vous trouverez des personnes avec des croyances différentes. Les architectures sont des concepts permettant de concevoir de meilleures solutions.
Outre la communication modèle-vue, il existe une autre contradiction concernant la logique métier dans MVC. Beaucoup de gens croient que toute la logique métier doit être un seul modèle (voir cette question SO ), par contre le lien partagé par Florian (dans sa réponse) indique que la logique métier doit être sur le contrôleur.
En dehors de cela, il est possible de diviser la logique applicative en logique applicative (la mettre sur le contrôleur) et en login de domaine (la mettre sur le modèle).
Ainsi, la morale de l'histoire est que MVC signifie que modèle, vue et contrôleur doivent être séparés. Autre que cela, ce qui vous convient le mieux.
L'utilisateur remplit le formulaire de mise à jour (Affichage)
Formulaire d'envoi d'utilisateur
Le contrôleur lie les données de formulaire à UserUpdateDTO
DTO et UserModel sont des POJO, mais DTO n'a ni identifiant ni nom d'utilisateur car nous ne pouvons pas mettre à jour le nom d'utilisateur.
Une autre différence est que la classe Model a des relations et des associations mais que DTO stocke uniquement des données et que nous pouvons y ajouter des validateurs JSR 303.
Les contrôleurs disent que la couche de service doit être sauvegardée
La couche service dit à la couche DAO de conserver les données
Je suis avec le camp qui dit que la vue ne doit jamais communiquer avec le modèle. Le contrôleur doit toujours être le spécialiste de tout, il décide ensuite quoi faire (valider, demander des données au modèle, etc.).
J'ai tendance à le voir plus comme un problème d'organisation que n'importe quoi d'autre.
Comme beaucoup d’indications sont suggérées sur les raisons pour lesquelles view & model devrait interagir librement dans différents contextes, mais la principale raison sous iOS de rendre Controller est le médiateur entre eux est d’éviter les dépendances de Model & View dans votre base de code et de nous permettre de les réutiliser. soit modéliser ou voir selon les besoins avec l'évolution de l'iOS.
Dans la mesure où nous pourrions avoir besoin de conserver les mises à jour de nos applications dans UI / UX ou Modèle, voire dans les deux cas, il ne devrait pas produire de code de dépendance de mode entre le modèle et la vue. Si vous souhaitez modifier la couche Présentation de votre application, procédez changez-le, vous pourrez toujours réutiliser le même modèle et vice-versa.
Bien que je convienne que MVC sous iOS génère des ViewControllers géants contenant de nombreuses logiques et gérant tout type de choses autres que celles auxquelles il est destiné. Il est donc préférable d’utiliser MVVM ou les contrôles de présentation pour rendre votre base de code plus flexible et plus facile. à lire et à maintenir avec des ViewControllers plus petits.
Cela pourrait aider ceux qui recherchent des ViewControllers plus petits dans iOS:
Sur le Web, tout le monde appelle son découplage MVC.
Certaines technologies, telles que C #, utilisent MVVM car il n’existe aucun lien entre la vue et une autre, tout passe par le localisateur de service et lie les variables.
Sur le MVC pur, la vue communique directement avec le modèle et inversement. Le contrôleur n’est présent qu’en cas de changement.
Et puis, il y a celui appelé PAC (Presentation Abstraction Control). Dans cette architecture, la vue et le modèle ne se parlent pas. Le contrôleur est le seul autorisé à faire quoi que ce soit avec la vue ou le modèle. Les gens confondent souvent cela avec MVC.
Vous verrez une meilleure explication ici: http://www.garfieldtech.com/blog/mvc-vs-pac
la source
Pour moi, l’objectif fondamental d’une architecture est de ne pas entraver les futures tentatives de refactorisation. En règle générale, les vues qui interagissent directement avec les modèles répondent à cette exigence et il est relativement clair que ce n'est pas le cas.
Quand une vue devient trop intime avec un modèle, un ViewModel peut être une belle chose, mais c'est généralement le cas pour moi que les cas où elle est appelée sont minoritaires.
la source
En MVC , Paul Hegarty a tort. Le contrôleur concerne les événements utilisateur, pas la communication modèle-vue. En MVC classique , la ou les vues observent le modèle (motif Observer).
Avec le gars entre la médiation, le modèle devrait être appelé MVP . En fait, la plupart de ce que l'on présente aujourd'hui comme MVC est en réalité plus proche de MVP.
Ensuite, il y a MVVM, qui est quelque chose de similaire aux deux, et pourtant un peu différent, qui existait il y a longtemps ... il est préférable de le voir comme deux MVC / MVP liés ensemble par un objet viewmodel - le "client" MVC a viewmodel son modèle, et le "serveur" MVC a le viewmodel comme vue.
la source
Puisque vous posez des questions sur le contenu de ces conférences à Stanford en particulier, il convient de considérer deux aspects de la position de Hegarty:
la source
Je suis d'accord avec Paul Hegarty et pense que la vue ne doit pas connaître le modèle. Ce n'est pas si difficile à réaliser, mais cela apporte des avantages supplémentaires à votre conception et à votre flexibilité future.
Dans les petites applications (généralement de bureau) où je voudrais éviter les classes ViewModel "factices" et garder les choses simples, j'utilise également l'interface IModel (voir la réponse ci-dessus) et veille à ce que Model n'ait aucune idée de la vue (utiliser les abonnés comme dans le MVC classique).
De plus, dans ce cas, le contrôleur est associé à la vue et par souci de simplicité, je ne les sépare pas toujours clairement.
La deuxième approche «simplifiée» convient si vous pouvez avoir plusieurs vues pour le même modèle, mais je ne le recommanderais pas si vous souhaitez utiliser la même vue pour différents modèles. Par différent, je veux dire très différent par nature et pas seulement par les classes de test JUnit qui "suivent" le modèle principal.
la source
Je crois qu'il n'y a pas de règle absolue pour cela, cela dépend totalement de vos besoins.
Vous trouverez des personnes avec des croyances différentes. Les architectures sont des concepts permettant de concevoir de meilleures solutions.
Outre la communication modèle-vue, il existe une autre contradiction concernant la logique métier dans MVC. Beaucoup de gens croient que toute la logique métier doit être un seul modèle (voir cette question SO ), par contre le lien partagé par Florian (dans sa réponse) indique que la logique métier doit être sur le contrôleur.
En dehors de cela, il est possible de diviser la logique applicative en logique applicative (la mettre sur le contrôleur) et en login de domaine (la mettre sur le modèle).
Ainsi, la morale de l'histoire est que MVC signifie que modèle, vue et contrôleur doivent être séparés. Autre que cela, ce qui vous convient le mieux.
la source
J'utilise DTO pour la communication modèle-vue.
Par exemple:
la source
Je suis avec le camp qui dit que la vue ne doit jamais communiquer avec le modèle. Le contrôleur doit toujours être le spécialiste de tout, il décide ensuite quoi faire (valider, demander des données au modèle, etc.).
J'ai tendance à le voir plus comme un problème d'organisation que n'importe quoi d'autre.
la source
Comme beaucoup d’indications sont suggérées sur les raisons pour lesquelles view & model devrait interagir librement dans différents contextes, mais la principale raison sous iOS de rendre Controller est le médiateur entre eux est d’éviter les dépendances de Model & View dans votre base de code et de nous permettre de les réutiliser. soit modéliser ou voir selon les besoins avec l'évolution de l'iOS.
Dans la mesure où nous pourrions avoir besoin de conserver les mises à jour de nos applications dans UI / UX ou Modèle, voire dans les deux cas, il ne devrait pas produire de code de dépendance de mode entre le modèle et la vue. Si vous souhaitez modifier la couche Présentation de votre application, procédez changez-le, vous pourrez toujours réutiliser le même modèle et vice-versa.
Bien que je convienne que MVC sous iOS génère des ViewControllers géants contenant de nombreuses logiques et gérant tout type de choses autres que celles auxquelles il est destiné. Il est donc préférable d’utiliser MVVM ou les contrôles de présentation pour rendre votre base de code plus flexible et plus facile. à lire et à maintenir avec des ViewControllers plus petits.
Cela pourrait aider ceux qui recherchent des ViewControllers plus petits dans iOS:
http://blog.xebia.com/simplification-of-ios-view-controllers-mvvm-or-presentation-controls/
la source