Modèle-Vue-Contrôleur – Modèle actif – comportementModèle-Vue-Contrôleur dans Android
Vers 2011, quand Android a commencé à devenir de plus en plus populaire, des questions d’architecture sont naturellement apparues. Comme MVC était l’un des patterns d’interface utilisateur les plus populaires à l’époque, les développeurs ont essayé de l’appliquer à Android également.
Si vous recherchez sur StackOverflow des questions comme « Comment appliquer MVC dans Android », l’une des réponses les plus populaires a déclaré que dans Android, une activité est à la fois la vue et le contrôleur. Avec le recul, cela semble presque fou ! Mais, à ce moment-là, l’accent principal était mis sur le fait de rendre le modèle testable et généralement le choix d’implémentation pour la vue et le contrôleur dépendait de la plateforme.
Comment appliquer le MVC dans Android
De nos jours, la question de savoir comment appliquer les patterns MVC a une réponse plus facile à trouver. Les activités, les fragments et les vues devraient être les vues dans le monde MVC. Les contrôleurs devraient être des classes séparées qui n’étendent ou n’utilisent aucune classe Android, et même chose pour les modèles.
Un problème se pose lors de la connexion du contrôleur à la vue, puisque le contrôleur doit dire à la vue de se mettre à jour. Dans l’architecture passive Model MVC, le contrôleur doit détenir une référence à la vue. La façon la plus simple de le faire, tout en se concentrant sur les tests, est d’avoir une interface BaseView, que l’Activité/Fragment/Vue étendrait. Ainsi, le contrôleur aurait une référence à la BaseView.
Avantages
Le pattern Modèle-Vue-Contrôleur supporte fortement la séparation des préoccupations. Cet avantage augmente non seulement la testabilité du code, mais il le rend également plus facile à étendre, permettant une implémentation assez facile de nouvelles fonctionnalités.
Les classes Model n’ont pas de référence aux classes Android et sont donc simples à tester à l’unité. Le contrôleur n’étend ou n’implémente aucune classe Android et doit avoir une référence à une classe d’interface de la vue. De cette façon, les tests unitaires du contrôleur sont également possibles.
Si les vues respectent le principe de responsabilité unique, alors leur rôle est juste de mettre à jour le contrôleur pour chaque événement utilisateur et juste d’afficher les données du modèle, sans implémenter aucune logique métier. Dans ce cas, les tests UI devraient être suffisants pour couvrir les fonctionnalités de la vue.
La vue dépend du contrôleur et du modèle
La dépendance de la vue vis-à-vis du modèle commence à être un inconvénient dans les vues complexes. Afin de minimiser la logique dans la vue, le modèle devrait être capable de fournir des méthodes testables pour chaque élément qui doit être affiché. Dans une implémentation active du Modèle, cela augmente exponentiellement le nombre de classes et de méthodes, étant donné que des Observateurs pour chaque type de données seraient nécessaires.
Du fait que la Vue dépend à la fois du Contrôleur et du Modèle, les changements dans la logique de l’IU pourraient nécessiter des mises à jour dans plusieurs classes, diminuant la flexibilité du pattern.
Qui gère la logique UI ?
Selon le pattern MVC, le contrôleur met à jour le modèle et la vue obtient les données à afficher à partir du modèle. Mais qui décide de la manière d’afficher les données ? Est-ce le Modèle ou la Vue ? Prenons l’exemple suivant : nous avons un User
, avec un prénom et un nom de famille. Dans la vue, nous devons afficher le nom de l’utilisateur comme « Nom, Prénom » (par exemple, « Doe, John »).
Si le rôle du Modèle est juste de fournir les données « brutes », cela signifie que le code dans la vue serait:
String firstName = userModel.getFirstName();
String lastName = userModel.getLastName(); nameTextView.setText(lastName + ", " + firstName)
Cela signifie donc que ce serait la responsabilité de la vue de gérer la logique UI. Mais cela rend la logique de l’interface utilisateur impossible à tester à l’unité.
L’autre approche consiste à faire en sorte que le modèle expose uniquement les données qui doivent être affichées, en cachant toute logique métier à la vue. Mais alors, nous nous retrouvons avec des modèles qui gèrent à la fois la logique métier et la logique d’interface utilisateur. Ce serait testable à l’unité, mais alors le Modèle finit, implicitement par être dépendant de la Vue.
String name = userModel.getDisplayName(); nameTextView.setText(name);
Conclusion
Dans les premiers jours d’Android, le pattern Modèle-Vue-Contrôleur semble avoir dérouté beaucoup de développeurs et conduit à un code difficile, voire impossible à tester à l’unité.
La dépendance de la vue par rapport au modèle et le fait d’avoir une logique dans la vue ont orienté notre code-base vers un état dont il était impossible de se remettre sans refactorer complètement l’application. Quelle était la nouvelle approche en matière d’architecture et pourquoi ? Découvrez-le en lisant cet article de blog.