Chapter 31. Hey Fred, Can You Pass Me the HashMap?

Kirk Pepperdine

Picture the scene: an old, cramped office with several old wooden desks set back-to-back. Each desk equipped with an old black rotary phone and ashtrays dotted about. On one of the desks is a black HashMap that contains an ArrayList filled with customer data. Sam, needing to contact Acme Inc., scans the office looking for the HashMap. Eyes darting, he spots the HashMap and shouts out, “Hey Fred, can you please pass me the HashMap?” Can you picture that…yup, I didn’t think so…

An important part of writing a program is the development of a vocabulary. Each word in that vocabulary should be an expression of something that is part of the domain we’re modeling. After all, it is this code expression of our model that others will have to read and understand. Consequently, our choice of vocabulary can either help or hinder understanding of our code. Oddly enough, the choice of vocabulary impacts much more than readability: the words we use affect how we think about the problem at hand, which, in turn, impacts the structure of our code, our choice of algorithms, how we shape our APIs, how well the system will fit our purpose, how easily it will be maintained and extended, and, finally, how well it will perform. Yes, the vocabulary we develop when writing code matters a lot. So much so that keeping a dictionary at hand can be strangely useful when writing code.

Returning to the ridiculous example, of course, no one would ask for the HashMap. You’d most likely draw a blank stare from Fred if you asked him to pass the HashMap. Yet when we look at how to model the domain, we hear about the need to look up customer contact data that is organized by name. That screams HashMap. If we dig deeper into the domain, then we’ll likely discover that the contact information is written on an index card that is neatly packed away in a Rolodex. Replacing the word HashMap with the word Rolodex not only offers a better abstraction in our code but it will also have an immediate impact on how we think about the problem at hand, and it offers a better way to express our thoughts to the reader of our code.

The takeaway here is that technical classes rarely have a place in the vocabulary of the domains we’re working in. Instead, what they offer are building blocks for deeper, more meaningful abstractions. The need for utility classes should be a red flag that you’re missing an abstraction. Additionally, technical classes in APIs should also be a red flag.

For example, consider the case where a method signature takes a String to represent a first name and a String for a last name. These are used to look up data held in a HashMap:

return listOfNames.get(firstName + lastName);

The question is, what is the missing abstraction? Having two fields forming a key is commonly known as a composite key. Using this abstraction we get:

return listOfNames.get(new CompositeKey(firstName, lastName));

When you make this change in a benchmark, the code runs three times faster. I would argue it is also more expressive: using CompositeKey better expresses the essence of the problem at hand.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.171.20