Selon la page wikipedia pour l'architecture MVC , la vue est libre d'être notifiée par le modèle, et est également libre d'interroger le modèle sur son état actuel. Cependant, selon cours de Paul Hegarty sur iOS 5 à Stanford, leçon 1, page 18 toute interaction doit passer par le contrôleur, avec Model et View qui ne sont jamais censé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 entend le design en tant que tel.
Comment expliquez-vous ces deux points de vue opposés?
Il s'agit d'un sujet controversé dans MVC/MVVM. Certains disent qu'il est OK pour la vue d'accéder directement aux modèles, 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. Donc, avec ce concept à l'esprit, permettre à la vue d'accéder directement aux modèles crée une dépendance que vous ne voudrez peut-être pas avoir. D'un autre côté, l'encapsulation des modèles dans les ViewModels est souvent fastidieuse et peu utile car les ViewModels ont tendance à agir simplement comme une transmission aux modèles.
J'aime l'approche selon laquelle vos modèles implémentent une interface particulière, appelons-la IModel. Votre classe ViewModel peut alors proposer des instances d'objets qui implémentent IModel pour la consommation View. La vue sait simplement qu'elle fonctionne avec les objets IModel qu'elle obtient du ViewModel. Cela supprime le code d'encapsuleur ViewModel superflu et masque l'implémentation concrète d'IModel dans la vue. Vous pouvez ultérieurement échanger une implémentation d'IModel pour une autre sans affecter la vue d'un bit.
Sur le Web, tout le monde appelle leur découplage MVC.
Certaines technologies, telles que C #, utilisent MVVM car il n'y a pas de lien entre la vue et toute autre, tout passe par le localisateur de service, liant les variables.
Sur MVC pur, la vue parle directement avec le modèle et vice-versa. Le contrôleur n'est là que lorsqu'un changement survient.
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
Pour moi, l'objectif fondamental d'une architecture est qu'elle n'entrave pas les futures tentatives de refactoring. En règle générale, les vues interagissant directement avec les modèles répondent à cette exigence, et il est relativement clair quand ce n'est pas le cas.
Lorsqu'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 instances où il est demandé sont minoritaires.
Dans MVC , Paul Hegarty a tort. Le contrôleur concerne les événements utilisateur, pas la communication modèle-à-vue. En classique MVC , la ou les vues observent le modèle (modèle d'observateur).
Avec le gars entre deux faisant la médiation, le modèle devrait être appelé MVP , et en fait, la plupart de ce qui est aujourd'hui présenté comme MVC, est en fait plus proche à MVP.
Ensuite, il y a MVVM qui est quelque chose de similaire aux deux, et pourtant un peu différent, et qui existait depuis longtemps ... il vaut mieux le voir comme deux MVC/MVP liés ensemble par l'objet viewmodel - le MVC "client" a viewmodel comme modèle, et le MVC "serveur" a le viewmodel comme vue.
Puisque vous posez des questions sur le contenu de ces conférences de Stanford en particulier, cela vaut la peine de considérer deux choses au sujet de la position de Hegarty:
Je crois qu'il n'y a pas de règle stricte pour cela, cela dépend totalement de vos besoins.
Vous trouverez des gens avec des croyances différentes. Les architectures sont des concepts pour aider à concevoir de meilleures solutions.
Hormis la communication vue modèle, il existe une autre contradiction concernant la logique métier dans MVC. Beaucoup de gens pensent que toute la logique métier doit être un modèle (voir cette SO question ), d'autre part le lien partagé par Florian (dans sa réponse) dit la logique métier doit se trouver sur le contrôleur.
En dehors de cela, il est possible de diviser la logique métier en logique d'application (mettez-la sur le contrôleur) et connexion au domaine (mettez-la sur le modèle).
Ainsi, la morale de l'histoire est que MVC signifie que le modèle, la vue et le contrôleur doivent être séparés. A part ça, ce qui vous convient le mieux.
Je suis d'accord avec Paul Hegarty et je 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ù j'aimerais éviter les classes ViewModel "factices" et garder les choses simples, j'utilise également l'interface IModel (voir la réponse ci-dessus) et je fais attention à ce que Model n'ait aucune idée de la vue (utilisez des abonnés comme dans le MVC classique).
Dans ce cas également, le contrôleur est tourné pour être assez couplé à la vue et pour plus de simplicité, je ne les sépare pas toujours clairement.
La deuxième approche "simplifiée" est OK lorsque 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. Sous différent, je veux dire vraiment différent par nature et pas seulement les classes de test JUnit qui "suivent" le modèle principal.
J'utilise DTO pour la communication vue modèle.
Par exemple: