Essayer de gérer l'état d'une fonction par l'utilisation de booléens pose plusieurs problèmes fondamentaux. Le premier est souvent appelé "explosion booléenne". Pour chaque booléen que nous ajoutons à une fonction, nous augmentons le nombre d'états possibles à un taux de 2^n où n est le nombre de booléens. En faisant le calcul quelques fois seulement, on obtient rapidement une quantité absurde d'états.
Le deuxième problème est que beaucoup de ces états sont des "états impossibles", des états dans lesquels notre application ne devrait jamais se trouver. Par exemple si on gère un état pour un animal avec un booléen estVivant est un autre estEntrainDabboyer on se rend compte qu'on ne peut pas être mort et être entrain d'aboyer en même temps. Pourtant au fur-et-à-mesure que le nombre de booléen s'enchainent et complexifie notre état, il y a de plus en plus de chances qu'à un moment on se retrouve dans un état comme celui-ci, ce qui ne devrait pas arriver.
Pour résoudre ce problème une manière saine est d'énumérer les états possibles et les évènement qui permettre de transitionner d'un état à un autre de manière déclarative, plutôt que de manière impérative.
Ce qui suit m'a pris quelques années à apprendre et surtout comprendre et m'a valu nombre d'essais et d'erreurs dans les logiciels que j'ai conçus. Je vais tenter de vous l'illustrer avec un exemple : Imaginons un logiciel d'achat de Pizzas, on choisit une quantité puis on clique sur « commander
Une approche naïve avec React serait d'avoir un formulaire de la sorte où l'ont gère la quantité et l'état d'envoi avec deux booléens.
Par la suite on nous demande de gérer des erreurs, puis comme le traitement du formulaire prends un certains temps, on nous demande de gérer un état de soumission du formulaire qui désactive le bouton pendant le chargement.
Nous sommes donc à 3 états booléens, soit 2^3 états possibles, soit 8 états possibles ce qui commence à faire.
Comme vous pouvez le voir, cela devient très verbeux et les possibilités d'erreurs et d'oublies sont assez probables.
Mais, à ce stade, nous devons nous poser une question : est-ce qu'on veut vraiment être le prochain développeur à travailler sur ce formulaire ?
Je ne pense pas. Le code est complexe. Il y a des états à gauche et à droite. Il y a même des paramètres à des endroits où nous ne sommes même pas sûrs d'en avoir besoin. Et nous essayons d'éviter de mettre notre composant dans des états impossibles.
On peut constater que le nombre d'États commence à augmenter très rapidement. Mais avons-nous réellement autant d'états dans notre programme ? Notre formulaire utilise actuellement trois booléens, mais a-t-il vraiment huit états ? Non, la plupart de ces états sont impossibles. Par exemple, nous ne pouvons pas être dans un état où isSuccess, error et isSubmitting deviennent tous vrais. C'est impossible.
Alors pourquoi donnons-nous à nos programmes la possibilité d'être dans des états impossibles ?
Parce que nous n'énumérons pas.
L'énumération, qui consiste à identifier un ensemble de choses une par une, est un moyen simple mais efficace de rendre nos programmes un peu plus robustes.
Compte tenu des mêmes exigences, on rend compte que notre formulaire ne peut se trouver que dans une poignée d'états. Énumérons-les :
Remarquons à quel point il est simple d'envoyer des événements et de s'assurer que notre composant est dans le bon état. Nous avons également beaucoup moins de conditions et de guards qu'auparavant. En éliminant l'existence d'états impossibles, nous avons créé un code dans lequel nous pouvons avoir une grande confiance.
Maintenant reposons-nous la question « souhaite-t-on vraiment être le prochain développeur à travailler sur ce formulaire ? »
En ce qui me concerne la réponse serait oui, mais bien évidemment il existe des outils qui nous permettre d'encore mieux représenter la gestion de nos états. Cela est présenté dans un autre article qui explique comment gérer l'état d'un jeu mobile à 3 étapes par tours en utilisant la librairie X-State