BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Actualités Facebook : MVC ne scale pas, utilisez plutôt Flux (mise à jour)

Facebook : MVC ne scale pas, utilisez plutôt Flux (mise à jour)

Favoris

Cet article a été mis à jour à l'appui des retours de la communauté et de la réaction de Jing Chen, de Facebook (cf. section "Mise à jour" ci-dessous).

Facebook est arrivé à la conclusion qu'MVC ne satisfaisait pas ses besoins de scalabilité et a décidé de le remplacer par un autre pattern : Flux.

Durant la récente session Hacker Way: Rethinking Web App Development at Facebook, tenue lors de la conférence F8, Tom Occhino, Engineering Manager chez Facebook, a affirmé que pour leur base de code "plutôt" importante et la taille de leur organisation, "MVC devenait rapidement vraiment compliqué" et a conclu que MVC n'était pas scalable. La complexité du système évoluait de façon exponentielle à chaque fois qu'une fonctionnalité était introduite, rendant le code "fragile et imprévisible". Ceci est devenu un problème sérieux pour les développeurs découvrant une nouvelle partie du code car ils se sont mis à avoir peur d'y toucher et de casser quelque chose. Par conséquent, Facebook a choisi d'abandonner MVC.

Pour résoudre ce problème, il était nécessaire de "structurer le code de sorte à le rendre plus prévisible". C'est ce qui a été fait avec Flux et React. Flux est une architecture système qui promeut un flux de données unique et directionnel à travers une application. D'après Occhino, React est un framework JavaScript pour construire des interfaces utilisateur Web "prévisibles" et "déclaratives" qui a permis à Facebook d'avancer plus rapidement dans leurs développements d'applications Web.

Jing Chen, développeur chez Facebook, a ajouté qu'MVC était bon pour les petites applications mais que la complexité explosait lorsque de nombreux modèles et les vues correspondantes étaient ajoutés à un système, comme l'illustre le diagramme ci-dessous :

Une telle application sera difficile à comprendre et à debugger, en particulier à cause des éventuels flux de données bidirectionnels entre les modèles et les vues, ce qui, d'après Chen, conduit à proposer la conception alternative de Flux représentée ci-dessous :

Le Store contient toutes les données de l'application et le Dispatcher remplace le Controller initial en décidant comment le Store doit être mis à jour lorsqu'une Action est déclenchée. La View est également mise à jour lorsque le Store change, éventuellement en générant une Action pour traitement par le Dispatcher. Ceci garantit un flux unidirectionnel des données à travers les composants du système. Un système avec de multiples Stores ou Views peut être vu comme n'ayant qu'un seul Store et qu'une seule View puisque les données ne s'écoulent que dans un sens et que les différents Stores et Views n'interagissent pas entre eux directement.

La page GitHub de React explique Flux, le Dispatcher et les Stores plus en détail :

Le Dispatcher est le concentrateur qui gère tout le flux de données dans une application Flux. Il s'agit essentiellement d'un ensemble de callbacks vers les Stores. Chaque Store s'enregistre lui-même et fournit une callback. Quand le dispatcher répond à une Action, le payload de données fourni par les Actions est envoyé aux Stores via les callbacks enregistrées.

Lorsqu'une application prend de l'ampleur, le Dispatcher devient de plus en plus vital car il peut gérer les dépendances entre Stores en invoquant les callbacks dans un ordre spécifique. Les Stores peuvent, de façon déclarative, attendre que les autres Stores aient fini leur mise à jour et se mettre ensuite eux-mêmes à jour en fonction de cela.

Les Stores contiennent l'état et la logique de l'application. Leur rôle est plus ou moins similaire à celui d'un modèle en MVC traditionnel, sauf qu'ils gèrent l'état de plusieurs objets, ils ne sont pas des instances d'un seul objet. Ils ne sont pas non plus l'équivalent des collections Backbone. Plus que de gérer simplement une collection d'objets et leur mapping avec la base de données (ORM), les Stores gèrent l'état de l'application pour un domaine particulier dans l'application.

Ce qui est important, d'après Chen, est que la couche de données finalise la mise à jour des vues avant qu'une quelconque action ne soit déclenchée. Le Dispatcher peut être amené à rejeter des Actions s'il n'a pas fini de traiter une action précédente. Cette conception est particulièrement utile pour les Actions avec effet de bord comme des mises à jour d'autres vues. Ceci rend le code plus clair, facile à comprendre et à debugger par les nouveaux développeurs. Flux a aidé Facebook à éliminer une anomalie sur leur application de tchat, qui indiquait aux utilisateurs que ceux-ci avaient un nouveau message alors que ce n'était pas forcément le cas.

Un tutorial Flux TodoMVC, accompagné de son code source sont disponibles sur GitHub.

Bien que Facebook soit libre d'utiliser la conception qui lui semble convenir, une question persiste : est-ce que MVC scale ou pas ? Après tout, de nombreux sites Web l'utilisent.

 

Mise à jour : après publication de cet article, de nombreux développeurs ont commenté sur Reddit la position de Facebook sur MVC. Voici quelques-uns de ces commentaires, certains considérant que Facebook utilise mal MVC, d'autres que Facebook a bien fait.

giveupitscrazy :

Cela n'a pas de sens. Déjà, leur diagramme d'MVC est complètement faux. Ils décrivent un contrôleur unique prenant en charge de multiples modèles, alors qu'on voudrait très certainement séparer les contrôleurs soit en fonction des modèles avec lesquels ils interagissent, soit en fonction d'autres découpages logiques.

Bien sûr, une configuration telle qu'ils la décrivent ne fonctionnerait pas, mais cela n'est pas vraiment du MVC. Si vous comparez leur diagramme à un vrai diagramme comme celui-ci, vous vous rendrez compte qu'il n'y a pas de défaut inhérent à MVC appliqué aux applications Web.

balefrost :

Et... voilà le truc... leur diagramme de Flux est très proche de votre diagramme d'MVC. Ils réinventent MVC et lui donnent un nouveau nom. Aaargh !

hackinthebochs :

On dirait que cette architecture fait d'MVC quelque chose de centré sur les événements. Les "Stores" s'enregistrent (ainsi que toute dépendance, probablement) auprès du dispatcher ; le dispatcher traite les actions et s'assure qu'une chaîne correcte d'appels est effectuée. Toute la complexité qui consiste à assurer l'ordre des appels est déplacée des contrôleurs vers le dispatcher et les stores. Ceci devrait réduire la compréhension nécessaire pour modifier le comportement.

runvnc :

Il me semble, en regardant rapidement, même si je pense ne pas avoir encore tout compris parfaitement, que je suis d'accord avec l'idée générale.

L'utilisateur Reddit jingc09, qui semble être Chen d'après ses commentaires, a ajouté :

jingc09 :

Oui, c'est un slide délicat (celui avec le diagramme montrant de multiples modèles et vues et des flux de données bidirectionnels), en partie parce qu'il n'y a pas un consensus sur ce qu'est MVC exactement. Beaucoup de personnes ont des idées différentes de ce que c'est. Ce que nous mettons en cause, c'est le flux bidirectionnel de données, où lorsqu'un changement de boucle de retour a des effets en cascade.

Elle essaye aussi de clarifier le fait que le Dispatcher de Flux n'est pas un Contrôleur :

Une chose que je souhaite clarifier est que le dispatcher ne joue pas le même rôle que les contrôleurs. Il n'y a pas de logique métier dans le dispatcher. Nous utilisons le même code pour le Dispatcher dans plusieurs applications. Il s'agit juste d'un concentrateur fait pour que les évènements arrivent aux abonnés intéressés (les stores habituellement). Mais il est important dans Flux car il renforce la contrainte du flux de données unidirectionnel.

Chen commente l'explication suivante du contrôleur MCV donnée par Wikipedia :

Un contrôleur peut envoyer des commandes au modèle pour mettre à jour l'état du modèle (par exemple, éditer un document). Il peut aussi envoyer des commandes à la vue à laquelle il est associé pour changer la présentation du modèle (par exemple en scrollant dans un document).

Chen dit :

Un dispatcher ne peut rien faire de tout cela, les commandes doivent partir d'ailleurs (vues, réponses serveur, mises à jour directes) et passer par le dispatcher. https://github.com/facebook/react/blob/master/examples/todomvc-flux/js/dispatcher/Dispatcher.js devrait aider à se figurer cela.

D'après ces commentaires Reddit, il semble qu'il y ait quelques confusions sur ce qu'est MVC et comment celui-ci devrait être implémenté.

En examinant la position de Facebook sur MVC, nous avons deux observations :

1) Le premier slide semble vraiment surchargé avec trop de modèles et de vues. On peut se demander si ce cas peut vraiment se présenter dans la vie réelle. Le problème résolu par Facebook avec Flux était celui de l'application de chat, qui avait 3 vues.

2) Pourquoi est-ce que dans leur exemple d'MVC, la vue génère-t-elle un flux de données et donc est à l'origine du flux bidirectionnel ? Et pourquoi la vue génère-t-elle une Action dans le diagramme de Flux ? Une vue est juste une vue, rien d'autre. Est-ce que Facebook utiliserait mal MVC ?

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT