A lot of times while writing features, I have come across cases where essentially all I’m doing is writing a rule engine. A rule engine is what I’ve understood and can describe as — a module or function where the output is dependent on a set of pre-decided rules and obeyed by the input.
As an example, consider the rule engine for baby named Boo.
Boo is a simple baby. When she is hungry, she wants food. When she is sad, she cries. When she is happy, she laughs. Otherwise, she sleeps.
To write a function to represent what state Boo is in, one approach we can use is
const howIsBoo = (state) => {
if (state === ‘HUNGRY’) return ‘WANTS FOOD’;
if (state === ‘SAD’) return ‘CRYING’;
if (state === ‘HAPPY’) return ‘LAUGHING’
return ‘SLEEPING’
}
We can achieve the same result using a switch statement on the state
variable. Both the approaches are correct but can be made more efficient by using Objects.
const booFeelsTable = {
‘HUNGRY’: ‘WANTS FOOD’,
‘SAD’: ‘CRYING’,
‘HAPPY’: ‘LAUGHING’
}const howIsBoo = (state) => booFeelsTable[state] || ‘SLEEPING’;
With this approach
- We make the code cleaner and easier to read
- Eliminate the branching by the if-else ladder and make the rule engine a simple O(1) lookup
- Default evaluation does not need to wait for all conditions to get processed. If a key does not exist in the lookup table, it returns the default condition straightaway
Lookup tables are a simple pattern which can be used anywhere we need to evaluate multiple rules. Personally, my rule of thumb is anytime I need to evaluate more than 2 conditions, I convert the logic to a lookup table.