Friday, September 11, 2020

Keeping the Caller Busy

There are ways we could refactor the displayCart function, but consider a second what the caller is doing each time it wants to use the function.

Consider this simple code example:

// caller
String shoppingCartMessage = displayCart("You have %s", cart.size());

String otherMessage = displayCart("You saved %s", saved.size());

// common function
String displayCart(String template, int size) {
   if (size == 0) {
      return String.format(template, "no items");
   }
   return String.format(template, size > 1 ? "a total of " + size + " items" :
     " an item");
}

Each call requires the caller to calculate the size of the list that it’s holding. For two examples, that’s fine. If the caller has a variety of different sources of data, then it’s also fine.

Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Prep

But if it’s always the same source data, then getting each call site to do a wee calculation is not less efficient in terms of processing, but it’s less ideomatic and it’s more typing.

Given the object of the displayCart function is to describe a particular shopping cart, why is it not working out what data it needs from the cart itself?

This becomes more of a problem if the caller has to calculate several attributes of the source data in order to use a function on those data.

Conversely, this alternative:

String displayCart(String template, List<Item> cart) {
   int size = cart.size();
   ...
}

… is only a reasonable thing to do if the common function:

◉ is really about the source data

◉ can be coupled with the types involved

◉ is suitably broken down so it doesn’t become a monolith with too many responsibilities

The way to identify this smell is a gang of callers all busily calculating the same inputs from the same types of source data.

Related Posts

0 comments:

Post a Comment