Problems with Enumerations to avoid
Introduction
Most of today’s programming languages support Enums. These types have the power to be very descriptive while being a value type: An enum is a named constant that corresponds to an integer value type. Each member maps to a number that is used implicitly when calling this constant.
You may tend to use them a lot, because of there very descriptive nature. I was also fooled a long time ago about their use cases and benefits. Every ‘Type’ property in my code used to be represented by an Enum. Funny enough, I now despise them and consider them a code smell in most of the cases…
So why are you shooting yourself in the foot when you’re using them in your codebase?
The Problem
You started as most developers does, throwing enums here and there on every Entity. Your customer gender is an enum, your transaction type is an enum, your shipment status… So, you have basically enums all over the place in your codebase. And these properties are there for a reason, you either want to just store, and display them for the user OR they are considered an input for some business process you are doing later on.
I mean, why do we store entities if we are not using them right? You are mostly using them in your business process, so they are linked to some sort of logic in your code.
Now, you know about the Clean Code and SOLID principles. You’re a good boy and try to follow them to the letter…
Your entities are generally exposed to all your application’s business logic. Because this logic manipulates them to generate something. Enums can be accessed the same as any property. This access gives control to you and to the other developers on the project to do the famous switch for this particular enum.
What happens is that not everyone is as meticulous as you are, if you are 😉 so you will end up with A LOT of switches spread across the codebase, doing sometimes the same handling, and sometimes not. If that does not scare you, follow through to see why it should!
Here’s comes the fun part, each and every switch you used is strongly dependent on that enum. And as our business matures, our entities and domain mature with it. You will find yourself needing to change an Enum’s name, add, modify or remove some of the constants of one. What will you do then?
You will see your code breaking everywhere, because your colleague changed variable name, or he might be clever enough to change the order or it’s equivalent Integer.
Errors are not always compile-time, this can be far worse and turn into a self-destruction mode when you are basically parsing and converting from strings to enums.
You are smart enough to decouple your domain entities from your contracts, right? And how would you do that with enums, int or string conversion… And didn’t you find yourself debugging for an entire day why some feature started acting weird out of nowhere and it turns out the enum is not being parsed?
A Solution
That’s why, for me enums are just an unmanageable mess and a risk that should not be taken most of the time. Even if you’re very technical, things can go sideways without you knowing… Here’s some common solutions you might want to consider before using an enum:
– Good old Handle() functions
– You can go a step further and implement the strategy pattern
– That’s great! You can go above and beyond now and use Assembly scanning and Dependency injection…
Enums should be really your plan Z. There’s always use cases for one, but I find that very niche and should not be used everywhere.
It should really come with the warning, use with caution!