Avoid booleans by default
Booleans make maintaining and changing code needlessly error-prone. Use enums
instead.
Method parameters
What does the following function do?
updateState(state, true);
Specifically, what does true mean? What would it mean to be false?
Modern IDEs may give the parameter name as a hint, but it’s still cumbersome to read.
updateState(state, silent: true)
A boolean in a method implies that changing the boolean changes the behaviour, so there is a high likelihood of that method containing an if statement. So why not just make two separate methods and keep the methods shorter?
updateStateSilently(State state);
updateStateWithNotification(State state);
Here’s another scenario:
void updateState(State state, bool silent, bool isAdmin);
What happens when we want to make a change to the function signature, such as removing one of the booleans? We need to be very careful that we refactor appropriately - deleting the wrong parameter could incorrectly invoke admin privileges!
Again, ide tools may be able to handle this for you, but it’s not fool proof.
How about if we used an enum?
void updateState(State state, NotificationMode notificationmode, PrincipalStatus principalStatus);
// ...
void updateState(state, NotificationMode.SILENT, PrincipalStatus.USER);
Now, if we incorrectly deleted the wrong parameter, we’ll get a compilation error instead!
State
Sometimes, you might have a boolean field in an object.
Consider the following example of an Order in a financial exchange. Sometimes, a user may want to place an order onto the order book, but want it to be cancelled if it would immediately match with an opposite order already on the book (frequently used by market makers). We call this a ‘post only’ order.
NewOrder{
Symbol symbol,
Price price,
Quantity quantity,
boolean postOnly
}
As a developer, we’ve been tasked with implementing a new behaviour: if a post-only order would match, then instead of cancelling the order, we adjust the price of the order to be as close as possible to the original price without it matching.
We could add a new boolean to the object, or an enum that expresses the
behaviour of the post only order, but we’d only set it if the order was post
only to begin with. This makes for some unsightly code, with behaviours that
aren’t entirely predictable to a developer reading the code for the first time.
Instead, we could change the postOnly field from a boolean to an enum,
with three possible behaviours:
OnMatchBehaviour.EXECUTE
OnmatchBehaviour.CANCEL
OnmatchBehaviour.ADJUST
But because we used a boolean to start with, we now have to change many places
from true`` andfalse. We may also be making a breaking change to our API. If we had used anenum` in the first place, our change would have been much
easier to make.
I recommend using enums as much as you can instead of booleans. The enum
can have a boolean isSomething() method to be used in an if statement.
If you then need to add a third enum, removing the isSomething() method
will then result in a compilation failure, ensuring that you update the code in
all the correct places.
Alternatively, you could use a switch() statement without a default case, so
that a new enum also results in a compilation failure.