Un booléen ?

Même si je pense que pour la plupart le terme vous est familier, je vous fais un bref rappel.

Un booléen est un type de donnée qui peut prendre uniquement deux valeurs : vrai (true) et faux (false). On utilise les booléens quand on a besoin de stocker une information très simple pour laquelle vrai/faux suffit (exemple : isPanelOpen) ou quand on veut juste stocker un ensemble de condition sous forme de drapeau (isThisFeatureEnabled, isThisAnotherFeatureEnabled, etc.).

Le piège du booléen

Sans dire qu'il faut bannir totalement l'usage des booléens posez -vous la question de savoir si c'est bien la meilleure façon de représenter les choses. Typiquement l'exemple que je prenais : isPanelOpen est un cas courant. Cette variable sert à indiquer si le panneau est affiché ou non. En soi on se dit que c'est un bon choix mais en pratique ça dépend des cas.

Imaginons qu'on parle d'un panneau graphique sur un site web. Ce panneau on voudra animer son ouverture et sa fermeture. Dans ce cas là la solution la plus courante c'est ajouter un second booléen isOpeningOrClosing ou shouldAnimate pour indiquer qu'on est en cours d'animation. Et si on veut aussi afficher une icône de chargement pendant qu'on récupère les données à afficher ? Encore un nouveau booléen isLoading ? Et donc on rentre dans un cycle où continuellement on va ajouter des booléens pour exprimer des choses parfois contradictoires alors qu'on pourrait faire mieux ?

Il ne faut pas négliger les refactorisations qui risque d'entrainer des loupés et le fait que rien qu'à lire le code on risque de mal comprendre quelque chose… Sans compter les états incohérents, car on aura pas une seule représentation de l'état mais bien un ensemble de booléen pour représenter cet état.

Enum et Union Type à la rescousse !

Dans tous les langages (sauf erreur) on trouve une notion d'énumération. En TypeScript on utilisera plutôt des union type à base de chaîne de caractère.

Par exemple :

type PanelState = 'OPENED' | 'OPENING' | 'LOADING' | 'FEED' | 'CLOSING' | 'CLOSED' ;

Simplement en faisant ce changement on rend l'état de notre panneau beaucoup plus simple à comprendre et suivre quand on lit le code. De plus en cas de log/debug on verra directement l'état qu'on attend pour ce panneau. On sait aussi dans quel sens on doit animer ce qui peut être utile pour gérer certaines conditions (par exemple ne charger les données que en OPENING et pas en CLOSING).

On va aussi pouvoir étendre cette liste d'état avec l'aide du compilateur. En effet si on introduit des nouvelles valeurs on pourra facilement détecter qu'on a pas traité tous les cas dans des switchs ou autres.

C'est trop lourd comme solution !

C'est vrai que cette solution est tout de même plus lourde qu'un booléen en termes de consommation mémoire.

Mais soyons honnêtes : est-ce qu'on est à vraiment à quelques octets prêts sur nos machines dans la majorité des cas ? est-ce qu'il ne vaut mieux pas favorisé la qualité du code ? Et est-ce qu'on ne ferait pas moins de calcul en comparant seulement deux valeurs d'énumérations que plusieurs combinaisons de booléens ?

Penons le cas d'une énumération : dans le cas général une fois compilé on aura une comparaison de nombre entier pas de chaîne de caractère. Donc au final ce sera assez léger aussi. Surtout en sachant que les booléens sont souvent compilés avec des entiers 32bits pour accélérer les temps de compilation.

Dans le même temps pour le cas des unions type en TypeScript, c'est vrai qu'en réalité on crée des nouvelles chaînes de caractère, mais le coup je trouve qu'on y gagne tellement en lisibilité, et en simplicité de code que ça vaut le coup. Même pour effectuer des requêtes ou des remontés de résultat : un JSON c'est du texte, donc transféré 2-3 booléens avec leurs clés, c'est sans doute plus lourd que transférer une seule clé avec une chaîne de caractère.

Conclusion

Je ne vous dirais pas jeter les booléens dans 100% des cas mais plutôt de ne pas hésiter à les jeter quand on peut faire mieux. Même si on pourrait se passer totalement des booléens. Personnellement, j'essaie d'utiliser le moins possible de booléen, c'est mon crédo depuis quelque temps après plusieurs refactorisations assez longue et un peu complexe avec des transformations de booléen en union type pour pouvoir exprimer plus facilement des états.

Crédit photo : https://pixabay.com/photos/board-school-hostile-enemy-2294941/