Quand vous avez commencé ce cours, je vous ai précisé qu’on implémentait souvent des design patterns lors de la refactorisation du code. En effet, au fur et à mesure qu’une codebase grossit, le code peut devenir moins maintenable et va donc perdre en lisibilité.
Nous allons profiter de ce chapitre pour refactoriser quelques parties du code et notamment la gestion de l’état de l’utilisateur. Cela nous permettra de dire quand l’utilisateur est connecté et quand il ne l’est pas.
Utilisez un State Pattern pour gérer l’état de votre utilisateur
Avant d’aller plus loin, on ne perd pas les bonnes habitudes : voici l’issue relative à notre chapitre. Lisez-la avant de passer à la suite.
Pour rappel, voici le formulaire de connexion de notre page :
Si vous ne voyez pas ce formulaire de connexion, il est très probable que ce soit lié au LocalStorage. Vous allez donc devoir vider ce dernier avant de voir à nouveau le formulaire s’afficher.
Pour ce faire, ouvrez vos outils de développement, cherchez la section Stockage et regardez l’onglet Stockage local. Vous devriez avoir votre nom et votre prénom.
Comme le précise l’issue GitHub, l’objetModalForm
a actuellement une dépendance forte aux données utilisateurs, et on viole le principe de responsabilité unique.
Aujourd’hui, notre objet ModalForm
:
S’occupe d’une part d’afficher le formulaire de connexion ainsi que de la partie soumission du formulaire. C’est assez normal, c’est son job, après tout ; :)
S’occupe de vérifier si un utilisateur existe, grâce à la méthode
shouldDisplayForm
, et d’instancier un nouvel utilisateur, grâce à la méthodeonSubmitForm
. Nous allons nous occuper de sortir cette logique dans un objet associé.
Mais pourtant le code n’est pas forcément très complexe et est assez lisible. Il y a vraiment besoin de faire cela ?
Bonne remarque ! :)
En fait, actuellement, cela ne nous pose pas de problèmes puisque que nous dialoguons avec l’objet User
uniquement dans l’objet ModalForm
. Cela dit, si demain on est amené à dialoguer avec l’objet User
à plusieurs endroits, nous allons perdre en maintenabilité.
Nous allons donc devoir créer un State Pattern qui permettra :
De nous retourner un utilisateur, s’il existe ;
De nous dire si l’utilisateur est connecté ou non ;
De gérer les changements d’état de l’objet
User
.
Bon, maintenant que vous en savez plus sur ce qu’on va faire, intéressons-nous à ce fameux State Pattern. :)
Identifiez les caractéristiques du State Pattern
Un State Pattern est composé des éléments suivants :
Vous avez le Context. Cet objet va vous permettre d’une part de connaître le State courant, et d’autre part d’effectuer les modifications de State.
Vous avez le ou les States. Ce sont des objets qui composent l’objet Context.
Le principe d’un State Pattern est de gérer facilement les changements d’état d’une application. Par exemple, lorsque que vous réalisez des traitements asynchrones en JavaScript, vos promesses peuvent avoir trois états : pending
, fulfilled
et rejected
ou, en français, en cours de traitement, résolue et rejetée.
Mais au final, ça complique la base de code pour pas grand-chose ? On peut s’en passer, non ?
Alors, oui et non !
Oui, parce qu’ajouter un State Pattern peut sembler quelque chose d’assez verbeux : vous allez écrire beaucoup de code pour, au final, une petite fonctionnalité.
Non, parce que cela va vous permettre de suivre l’état de votre application beaucoup plus précisément. En appelant l’acteur Context, appelé UserContext
dans le cas de Filmo Patterns, vous allez être capable de savoir rapidement et précisément si un utilisateur est connecté ou non.
Implémentez un State Pattern
Vous vous souvenez de notre système de mise en envie du chapitre précédent ? Pour implémenter l’Observer Pattern, j’ai créé un dossier wishlist
et à l’intérieur de ce dossier, j’ai ajouté deux fichiers, Subject
et Counter
. On va faire pareil pour le State Pattern !
Je vais créer un dossier user
qui contiendra deux fichiers : Context
et State
; l’ensemble de mes états sera donc dans le dossier fichier js/user/State.js
.
Dans la vidéo ci-dessous, nous allons voir un exemple assez fréquent de State Pattern : un système de feu de signalisation. Vous verrez comment le Context gère les changements d’état d’une application !
Vous pouvez retrouver le code source de cet exemple ici.
À vous de jouer !
Voilà, c’est maintenant à votre tour d’implémenter un State Pattern pour résoudre notre issue GitHub.
Pour votre information, voici ce que j'ai déjà créé pour vous :
Le dossier
user
comprend les fichiersContext
etState
. Pour vous aider un peu, je vous ai aussi créé les objetsUserConnectedState
etAnonymousUser
; vous n’avez plus qu’à les coder.Les deux fichiers ont été reliés au fichier
index.html
.Je vous ai aussi précisé les lignes à décommenter dans l’objet
js/templates/FormModal.js
.L’objet UserContext aura comme propriétés
states
etcurrentState
, et comme méthodes,constructor
,getInitialState
etchange
.Chacun des states aura comme propriétés
isConnected
etUser
, et comme méthodes,constructor
etgetUser
.
Ne vous découragez pas si vous n’y arrivez pas du premier coup ! Ce sont des concepts complexes qui mettent du temps à être appris et compris !
Le code source contenant la solution de cet exercice se trouve sur la branche partie-4/chapitre-2-fin
.
En résumé
Le State Pattern permet de suivre l’état d’une application. Il est composé d’un Context et de plusieurs States.
Chaque State correspond à un des états possibles de l’application. Par exemple, pour un utilisateur, on pourrait avoir
connected
,anonymous
, etc.Le State Pattern est souvent bien pratique pour le débogage. Vous connaissez par avance dans quel état se trouve votre application, et vous centralisez vos changements d’état à un seul endroit.
Et voilà, vous venez de voir votre deuxième Behavioral Design Pattern. Grâce à ce dernier, l’apprentissage de React et surtout de Redux devrait être facilité. :)