Comprendre lâarchitecture MVVM sur Android đ±
En gĂ©nie logiciel de nombreux patrons de conception existent dans le but de rĂ©soudre des problĂšmes bien prĂ©cis, que ce soit pour remplir des exigences dâordre architecturale, de cohĂ©rence, dâadaptabilitĂ© et de respect des bonnes pratiques. Cela dit, certains se sont dĂ©marquĂ©s au fil du temps au sein de la communautĂ© de dĂ©veloppement Android, il sâagit de MVVM, MVC, MVP et MVI; Chacun ayant ses particularitĂ©s, ses avantages et ses inconvĂ©nients. Mais aujourdâhui nous nous focaliserons sur le design pattern le plus plĂ©biscitĂ© par les dĂ©veloppeurs Android selon de nombreux sondages: Model-View-ViewModel, communĂ©ment abrĂ©gĂ© MVVM. Quâest-ce que MVVM? Comment est-ce quâil fonctionne? Pourquoi Google le recommande comme le patron de conception idĂ©al pour architecturer son application Android? Tant de questions sâoffrent Ă nous, et câest avec un grand plaisir que cet article nous apportera des rĂ©ponses claires et prĂ©cises.
I. MVVM câest quoi concrĂštement ?
1. Généralités
DâaprĂšs Wikipedia, Le modĂšle-vue-vue modĂšle (en abrĂ©gĂ© MVVM, de lâanglais Model View ViewModel) est une architecture et une mĂ©thode de conception utilisĂ©e dans le gĂ©nie logiciel.
Apparu en 2004, MVVM est originaire de Microsoft et adaptĂ© pour le dĂ©veloppement des applications basĂ©es sur les technologies Windows Presentation Foundation (WPF) et Silverlight via lâoutil MVVM Light par exemple.
MVVM nait du besoin de sĂ©parer la logique mĂ©tier et lâaccĂšs aux donnĂ©es dâune application de son interface utilisateur, ceci dans le but dâaccroitre la rĂ©utilisabilitĂ© du code, et ainsi favoriser sa maintenabilitĂ© par le principe de âSeparation of concernsâ.
Il sera plus tard adoptĂ© par Google qui y apportera des modifications structurelles dans le cadre du dĂ©veloppement Android afin de rĂ©pondre aux problĂ©matiques technologiques de plus en plus Ă©voluantes de la plateforme. Le principe reste le mĂȘme, 3 couches bien distinctes gardant les mĂȘmes fonctions, mais lâapproche Android apporte ses propres singularitĂ©s technologiques comme LiveData, Lifecycles, bref, Android Architecture Components.
2. Structure
De maniÚre générale, MVVM est structuré en 3 grandes parties:
Model
Le modĂšle reprĂ©sente lâensemble des entitĂ©s et des modĂšles de donnĂ©es dont aura besoin la vue pour prĂ©senter les informations Ă lâutilisateur.
View
La vue reprĂ©sente la partie visible de lâiceberg, ce sont les interfaces graphiques (activitĂ©s, fragments), XML, les widgets, les animations, les textes et tous les composants en interaction directe avec lâutilisateur final. Elle constitue la partie visuelle de lâapplication, câest la vitrine qui prĂ©sente les informations fournies par le Model et traitĂ©es par le ViewModel
ViewModel
Le ViewModel reprĂ©sente la couche qui gĂšre toute la logique mĂ©tier de lâapplication, elle concerne les opĂ©rations de traitements qui sâopĂšrent entre la base de donnĂ©es et la vue, par exemple le formatage de donnĂ©es, lâenvoi de paramĂštres vers les requĂȘtes, la rĂ©ception des donnĂ©es.
3. Les avantages et inconvénients
Comme avantages de MVVM nous pouvons citer:
La maintenabilitĂ© : Avec une sĂ©paration claire des diffĂ©rents modules du projet, il yâa une meilleure organisation structurelle, le code est plus lisible, mieux architecturĂ© car respectant des standards bien dĂ©finis et donc plus facile Ă maintenir. Les fonctionnalitĂ©s Ă©tant regroupĂ©es dans dans le ViewModel, cela permet dâavoir des vues propres, dĂ©pourvues de code âspaghettisâ.
La testabilitĂ© : Avec MVVM chaque bout de code est Ă©crit de façon granulaire, les dĂ©pendances internes et externes sont sĂ©parĂ©es de la logique mĂ©tier et lâensemble des fonctionnalitĂ©s Ă tester. Ce qui rend le code bien plus testable.
La rĂ©utilisabilitĂ© et lâextensibilitĂ© du code : MVVM facilite la possibilitĂ© dâajout et de rĂ©utilisation du code par le principe de faible couplage de classes, cela a pour bĂ©nĂ©fice de diminuer les risques de lourdes dettes techniques lors de maintenances Ă©volutives.
Les inconvĂ©nients sont plus des contraintes dâordre techniques, et dĂ©pendent donc fortement du dĂ©veloppeur, par consĂ©quent cela demeure un sujet trĂšs subjectif.
II. MVVM recommandé par Google pour les applications Android
1. Architecture
Voici comment se prĂ©sente lâarchitecture MVVM pour le dĂ©veloppement Android. Google a dĂ©fini un ensemble de rĂšgles et de principes prenant en compte les diffĂ©rentes technologies de la plateforme afin de proposer une architecture cohĂ©rente et rĂ©pondant aux besoins techniques de lâĂ©cosystĂšme Android.
Le MVVM tel que recommandĂ© par Google se repose sur Android Architecture Components, qui est un des 4 piliers de lâĂ©cosystĂšme Jetpack.
Architecture Components est composé de:
Data Binding, Lifecycles, LiveData, Navigation et bien dâautres outils qui vous aident Ă concevoir des applications robustes, testables et maintenables.
Lifecycles et LiveData sont dâune importance capitale dans lâimplĂ©mentation de MVVM, car ils permettent de prendre en considĂ©ration les Ă©vĂ©nements qui entrent en jeu au cours de lâexistence de lâapplication, Lifecycle permet par exemple de ne pas refaire de requĂȘtes rĂ©seau lorsque le smartphone subit une rotation, mais plutĂŽt de conserver les donnĂ©es dans le cache et les recharger simplement sur la vue, Ă©vitant ainsi les fuites de mĂ©moire ou Memory leaks.
Cependant, de nombreux dĂ©veloppeurs font souvent une confusion entre lâutilisation de Flow et LiveData.
Astuce: Partez toujours du principe que le repository utilise Flow et le ViewModel, LiveData.
2. Implémentation
Afin de sâarrimer aux spĂ©cifications de Google, cet exemple est implĂ©mentĂ© Ă partir des technologies suivantes:
- Android Architecture Components (Lifecycle, LiveData, Room, ViewModel)
- Hilt (Pour lâinjection des dĂ©pendances)
- Kotlin coroutines (Pour la gestion des flux de données de façon asynchrone)
- Retrofit (Pour les appels HTTP)
Structure du projet
Le projet sera subdivisé en 7 parties, chacune ayant un rÎle bien précis:
database
: La base de données et ses objets(DAO, entités, mappers)
di
: Les injections de dependances.
model
: Les entités de notre modÚle de données.
network
: Les objets réponses pour appels réseaux, les mappers et les API.
repository
: Le Repository.
ui
: La vue et son viewModel
util
: Les classes utilitaires.
Il est Ă noter que la hiĂ©rarchisation des packages dĂ©pend parfois des prĂ©fĂ©rences et donc peut varier lĂ©gĂšrement dâun dĂ©veloppeur Ă lâautre, cependant le MVVM respecte toujours un certain formalisme de structure et de cohĂ©rence.
1. CrĂ©er lâobjet State pour la gestion des Ă©tats du rĂ©seau
Nous allons tout dâabord crĂ©er une classe utilitaire qui nous permettra de transmettre lâĂ©tat de nos requĂȘtes rĂ©seau Ă la vue.
2. Créer le Model
On rappelle que le modÚle englobe ici le repository, la source de données distante, la base de données locale, ainsi que les préférences partagées.
Network
BlogObjectResponse
On crĂ©e lâobjet qui sera chargĂ© de rĂ©cupĂ©rer les rĂ©ponses de notre API REST telles que formatĂ©es par le JSON.
BlogApi
Lâinterface qui aura pour rĂŽle dâexposer nos requĂȘtes HTTP vers la source de donnĂ©es distante (service web).
Mappers
Un mapper est une classe qui permet de formater correctement les donnĂ©es reçues Ă travers lâAPI afin de les utiliser de façon convenable, cela permet de rĂ©cupĂ©rer uniquement les donnĂ©es utiles, encoder ou dĂ©coder les attributs, les convertir en liste ou en tableaux en fonction de nos exigences.
Repository
MainRepository
Le repository câest le rĂ©pertoire oĂč proviennent toutes les donnĂ©es de lâapplication.
Notre MainRepository
aura donc pour objectif de faire appel aux mĂ©thodes de lâAPI distante, de la base de donnĂ©es locale ou des prĂ©fĂ©rences partagĂ©es, afin de nous retourner les donnĂ©es dont notre application aura besoin. Par ailleurs elle nous fera transmettre un message dâerreur ou de succĂšs grĂące Ă notre classe State.kt
en fonction du rĂ©sultat de nos requĂȘtes.
Database
BlogDatabase
CrĂ©ation de la base de donnĂ©es avec la librairie Room. Câest un ORM dĂ©veloppĂ© par Google, qui fournit une couche dâabstraction entre la base de donnĂ©es SQLite et nos donnĂ©es sous forme dâobjets. Elle a pour particularitĂ© sa facilitĂ© de prise en main et de dĂ©boggage.
BlogDAO
DAO ou Data Access Object, il sâagit dâinterfaces propres Ă chacun de nos objets chargĂ©es de regrouper les opĂ©rations de persistances de donnĂ©es (CRUD) liĂ©es Ă nos diffĂ©rentes entitĂ©s. Elles sont essentielles pour interagir avec la base de donnĂ©es. Chaque objet de la base de donnĂ©es possĂšde son interface DAO.
3. Créer le ViewModel
MainViewModel
Le ViewModel contient tous les traitements qui sâeffectuent dans le but de servir la vue, il est important de noter que chaque ActivitĂ©/Fragment possĂšde un et un seul ViewModel. Dans ce cas de figure, nous nâavons quâune seule fonctionnalitĂ©, et donc MainViewModel
qui est tout simple, permet de collecter les donnĂ©es (les articles du blog) Ă partir du repository en Ă©coutant lâĂ©tat de la requĂȘte afin de notifier le rĂ©sultat Ă MainActivity
.
Vous remarquerez lâutilisation de LiveData. En effet, MVVM repose sur la programmation rĂ©active dâoĂč la notion de LiveData qui sont des objets observables et lifecycle-aware, câest Ă dire quâils permettent dâĂ©couter les changements de comportements du ViewModel afin de traiter et communiquer les donnĂ©es Ă la vue de maniĂšre cohĂ©rente , tout en prenant en compte le cycle de vie des composants de la vue (lifecycle-aware).
4. Créer les vues
Notre partie vue sera composĂ© de lâactivitĂ©, de lâadapter pour la liste dâarticles du blog, de lâUI pour lâactivitĂ© en XML, de lâUI pour lâarticle en XML. Rien de bien compliquĂ© ! Nous nous attarderons cependant sur lâactivitĂ© et lâadapter.
BlogAdapter
MainActivity
Câest ici quâon constate la grande force de MVVM, le code est Ă©purĂ© et simplifiĂ©, car toute la logique mĂ©tier se trouve dĂ©sormais relayĂ©e au ViewModel. La vue nâa plus quâĂ Ă©couter son ViewModel Ă travers LiveData et sa mĂ©thode observe
pour adopter des comportements en fonction de lâĂ©tat des donnĂ©es reçu. Dans ce cas de figure prĂ©cis, il est question de peupler le RecyclerView avec les articles du blog en cas de succĂšs ou alors afficher un toast en cas dâĂ©chec de lâopĂ©ration.
Et le tour est jouĂ© ! đđ„
En utilisant Architecture Components, Kotlin Coroutines et Hilt, jâai crĂ©e une application qui dĂ©montre comme implĂ©menter simplement MVVM avec Hilt et Open API.
Pour plus de dĂ©tails, je vous invite Ă cloner le repo Github du projet afin dâapprĂ©hender avec plus de profondeur les diffĂ©rentes notions de MVVM. Vous pourrez lâamĂ©liorer si vous le souhaitez et y ajouter des fonctionnalitĂ©s pour vous exercer.
Les technologies et les concepts de dĂ©veloppement Ă©voluent de façon exponentielle, il nous revient donc de prĂ©server une veille technologique constante afin de rester Ă jour et produire des travaux de qualitĂ©, cependant, gardez toujours en tĂȘte quâun patron de conception est choisi en fonction du problĂšme rencontrĂ© et donc je vous recommande non pas dâen adopter un par dĂ©faut, ou parce que câest le favori du moment, mais dâen Ă©tudiez plusieurs afin de dĂ©cider lequel utiliser selon les problĂ©matiques que vous rencontrerez au quotidien dans les projets de dĂ©veloppement logiciel.
MERCI Ă vous dâavoir pris la peine de lire cet article, nâhĂ©sitez pas Ă laisser quelques applaudissements si vous avez appris de nouveaux concepts et surtout pour encourager lâauteur. đđđđ
Suivez Android Mood pour plus de nouveautés !
A la prochaine !
Reférences
Handling Lifecycles with Lifecycle-Aware Components
MVVM Architecture â Android Tutorial for Beginners â Step by Step Guide