At 40+ lines this is a lengthy function and upon reading it your initial reflex may be to split it. But length on its own is not the only factor that we should use to decide whether we should extract logic from a function or not.
A function should wrap a single logical operation and this is the case with this one. The only candidate for extraction in my mind is the logic inside the newTriePosition instanceof Leaf conditional statement which I’ve omitted for brevity.
Inside of it, we check whether an action should be fired and then continue to fire it. A good hint that this logic can be separated is the variable definitions at the beginning of the conditional block.
When you find yourself declaring multiple variables inside a conditional block, it means that you’re starting a new logical operation.
Another thing I want to emphasize is the sequence of guard clauses at the top of the function. These conditional statements check for common reasons not to execute the rest of the logic. I like that they’ve put them at a single level of indentation on the top.
The alternative would lead to more complex nested logic, nesting the implementation deeper and deeper.
In the handler function, we once again find many uses of the as keyword. It also requires the usage of additional brackets which make the code just slightly harder to follow.
Personally, I’d rather have yet another check to narrow down the type.
What the rest of the function is doing is traversing this Trie data structure that we mentioned and checking if there’s a match in it based on the pressed keys. Then if we find one, we execute the actions stored for the current sequence.
On a high level, this is what the whole library is doing.
I’ve emphasized the importance of using proper data structures before and Hotkey is a perfect example of how using the right one can reduce the complexity of the codebase.
The Radix Trie
Knowledge of data structures and algorithms is often overlooked in front-end development because of the lack of necessity to use them. So far I haven’t had to use a Trie in production code, and in full honesty, I didn’t know what a Radix Trie was before I dove into this library.
But it’s the understanding of these structures that helps us identify opportunities to utilize them in the first place. So I got even more excited when I saw the Radix Trie sitting in the heart of this small utility library.
A Trie is a tree-like data structure most often used for efficient string searching. Each node in it represents a character in the string and they’re ordered in a top-down manner. When multiple strings share the same prefix, we only add the extra character as a leaf child node to the last letter of the prefix.
|