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:
01 02 03 04 05 06 07 08 09 10 11 12 13 | // 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.
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:
1 2 3 4 | 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.
Published on Java Code Geeks with permission by Ashley Frieze, partner at our JCG program. See the original article here: Keeping the Caller Busy Opinions expressed by Java Code Geeks contributors are their own. |