dimanche 3 août 2014

MV oh et puis zut

Vous l'ignorez peut-être mais il existe plusieurs motifs de conception d'IHM dont le nom commence par Model-View. Aujourd'hui, j'en vois 3 :

  • Model-View-Controler
  • Model-View-Presenter
  • Model-View-ViewModel

Comme je m'ennuie en ce moment, je vais en faire une rapide description pour en dire ensuite le mal que j'en pense.

Model-View-Controler

Celui-ci est le plus connu. La plupart des frameworks pour faire du web propose de l'utiliser. En effet, il se marie bien avec l'aspect asynchrone du protocole HTTP où le serveur reçoit une requête et la traite pour renvoyer une réponse au client.

En gros, ça se présente comme ça :

L'utilisateur interroge le Controler. Celui-ci va aller chercher l'élément du Model attendu et va demander à une View de l'afficher. Quand vous avez une appli simple utilisant Django,par exemple, c'est exectement ce qu'il se passe.

Avec des protocoles synchrones, ou même en HTTP aujourd'hui avec websocket, la view peut-être notifiée de chaque modification du modèle et se mettre à jour facilement en implémentant le pattern Observer.

Je n'ai pas grand chose à dire sur MVC. C'est vraiment un truc de base, rencontré tellement souvent ! Son point faible est que la vue a une connaissance du modèle. Ceci peut éventuellement lui imposer de traverser plusieurs couches d'objets pour récupérer de l'information. Cela pousse également à considérer que le modèle est un ensemble d'agrégats de structures de données sans comportement destiné à faire du CRUD dans une base de données, qu'elle soit relationnelle ou pas. Et moi, un modèle qui ne présente pas de comportement, je trouve ça chiant.

Model-View-Presenter

Avec celui-là, l'histoire est un peu différente.

L'utilisateur arrive sur la View. Celle-ci possède une référence vers un Presenter, auquel elle relaie l'action demandée par l'utilisateur. Par exemple : afficher des données. Le Presenter se démerde pour aller fouiller dans le Model et ordonne à la vue d'effectuer l'action d'affichage.

Ce pattern n'est utilisable que si on peut donner (coder) des comportements aux vues, donc sur du client lourd ou dans le web sur des trucs un peu louches comme ASP et son Code Behind ou GWT et Vaadin en Java.

On commence à avoir un truc sympa. La view peut pousser comportements métiers au presenter (exemple : déménage le client John Doe). En retour, celui-ci commande le comportement de la vue (par exemple affiche la confirmation du déménagement puis montre l'agence la plus proche de son domicile). Charge à la vue d'implémenter les actions correspondantes correctement.

Autre intéret, on peut mocker la vue et l'injecter dans une instance de presenter pour les tests. Si la logique d'exposer des actions métiers et pas du simple CRUD est suivie pour le model, la view et le presenter on aura même des tests qui parleront métier, ce qui nous rapproche du graal, la spec exécutable ! La view elle-même peut suivre une logique task based UI

Avec les langages à interface, l'implémentation repose sur l'astuce suivante :

  • La view initialise son presenter en lui passant sa propre référence
  • Le presenter possède dans ces champs l'interface implémentée par la vue

Les griefs qu'on peut faire à ce pattern est d'abord qu'il semble être compliqué à comprendre. Il est dans tous les cas moins connu que MVC, ce qui permet de se faire mousser en soirée (MVC c'est as been, faut faire du MVP maintenant). D'autre part, avec les langages d'entreprise, ils poussent à faire plus d'interfaces. Et les interfaces, c'est rébarbatif à trimbaler.

Model-View-ViewModel

Alors, je vous le dit tout de suite : la pertinence de ce pattern n'est pas claire pour moi. Alors excusez-moi si j'en donne une vision abusivement simpliste pour pouvoir le dénigrer plus facilement.

Ici, l'histoire est que, comme pour le MVP, l'utilisateur arrive sur la vue qui va directement solliciter un objet ViewModel pour alimenter ses données.

Normalement, ce pattern s'appuie sur la possibilité de faire du data binding bidirectionnel. Ainsi, la vue n'a plus aucun comportement si ce n'est de se synchroniser avec le viewmodel.

Ce que je n'aime pas dans ce pattern, c'est d'abord son nom que je trouve mal choisi. Sérieux, il me donne l'impression qu'il y a un individu en trop dans le trio. Un jour les deux autres vont le dégager en lui demandant ce qu'il fout encore là !

L'intéret du pattern réside dans le fait que grâce au data binding, les données de la View sont simplement synchronisées avec le Model via le ViewModel. On ne s'embète plus avec la logique de requête.

Le point négatif par rapport à MVP est qu'on perd la possibilité de mettre du métier, avec un retour au CRUD bête et méchant.

Conclusion

MVC, MVP, MVVM… Ce qu'on peut dire de ces patterns, c'est qu'ils sont utilisables dans des technos graduellement restrictives. Si le MVC est devenu un standard de développement en pur Web, MVP et MVVM ne s'appliquent que si les technologies proposent un moyens d'associer la vue à une interface pour le premier ou du data binding pour le second.

Je trouve MVP très intéressant dans la mesure ou la logique d'afficage des données peut être cachée derrière des méthodes au nom évocateur, rendant le code plus lisible. Hélas, devoir faire du GWT ou de l'ASP est pour moi un prix lourd à payer.

Alors faute de mieux, pour mes besoins, je crois que je vais m'en tenir à l'approche MVC.