Avoid using boolean as the origin data as much as possible 🎉
In this post, I would like to write about my personal thought on why I think boolean should never be used as the source of data. Not only does it improve maintenance of our code but also assure impossible state becomes impossible. Stay tuned and read on guys 😎
Boolean is a common data type that supported by almost if not all programming languages to represent simple data state - true or false. And it's undoubtedly clear that state management is one of the hardest problems in programming. Speaking of the web landscape only, we have countless amount of solutions that have been trying to solve this problem from various flavor choices of technology - Redux, Elm, Vuex, Flux, Recoil, Jotai, Zustand, MobX, Svelte store, et cetera. Regardless of technical decision your teams make, they are most likely just about abstraction over primitive data types such as string, number, boolean, and so on. Upon my experience as professional UI engineer over the last half decades, boolean is just one of the worst choice when trying to pick perfect root data type for your application. Let's go over couple of examples to demonstrate my previous statement before going for a better / scalable solution 😊
First and foremost, boolean data type is very very very... hard to get right. We can start by thinking of the most basic example is light bulb state. It can be really tempting to use boolean to present its state such as isOn, isOff, etc because that's what we most likely see in real life from the bulb - either on or off. A good programmer always tries to optimize for changes as to assure scalable code - that's also what makes a good abstraction! If not ask me how to make perfect abstraction? I don't think anyone can answer that since "To error is human", we always make mistake and grow. Only time can tell if we make a good abstraction or not. Everything is a tradeoff. SOLID and Design Patterns should always be there as part of your tool belt 😃. Back to our light bulb example, what if we want to present its broken state or even its meta properties such as created, maximum capacity, and batter type. This is where things will start looking ugly with our original boolean state.
One real world example I have seen in my work at Axon is a Table which is used to show different information about evidences that match given query. At the beginning it's just meant to support typical evidence search feature. Everything looked good at this point. As time flew, business changes, new requirements come into play. Our engineers wanted to support new usage as to show evidences attached to a case which look 90% the same with original evidence. And they don't want to duplicate the code just to achieve 10% difference. They decided to go for a boolean so-called isCase. Later, more requirement comes in, this table needed to support case share type. Things started falling apart, it's again tempting for any new comers to follow the dirty track instead of making things right. The new boolean property was born with a name isCaseShare. And now, we started to see where things look real funky as below
<Table isCase isCaseShare ... />
At this point, only God could guess what our Table does given its interface above. We might want to call it the impossible state possible which it should not be. Let's see how we can tack this kind of problem 😁
The state machine and state chart is my favourite and go-to solution for any complex state management. It's scalable from simple toggle button to a complex one such as multi step form with visual diagram. Brilliant guys like Kent C Dodds even believes it is the future of state management. Stately makes all that happen by magnificent OSS so-called XState. And here is where I want to back the title of the post. State is represent using type literals - not boolean. We can model any state by using just concrete type to inform our systems about what is going on effectively and avoid a whole bunch of bugs might come from the impossible states. In our simple light bulb example, we could use state type instead of boolean and its possible values are on, off and broken. They are the main possible states of our light bulb. Now, isOn or isOff can become derived states instead of syncing it in the first place as the source of data. Other properties and infinite states can be included in so-called context which will go along during lifetime of our application. Please give state machine and statechart a try. It has changed my life for the better, and hopefully will be yours 😇
There you have it guys, my personal take on why I believe state chart and state machine should be used more widely in our IT industry not only to minimize bug counts, but also for the better quality of our software. Happy coding and until next time 🥳