Ok, straight up; I have a real bugbear with Utils classes. To me, they’re a real code smell. Like month old milk kinda smell. I gag a little. And like old milk, it only gets worse over time.
Let’s back up a bit; what do I mean by a Utils class? They can take many forms, but most are easy to spot, as then tend to have a `Utils` suffix, or `Helper`, on the class or file name. Within, you’ll find a hodgepodge of method names roughly connected together through tenuous concerns. A rather relevant example would be `PropertyUtils` – a class that contains “Utility methods” for a Property. So far, so normal – almost every codebase has a class like this. And on the outside, makes perfect sense; a class that contains methods to act on a property. Within, you might find methods like
Methods that don’t really fit anywhere, but conceptually fit with the `Property` object. Makes some sense, right?
But hang on a second; what does `Utility` actually mean? Well, if we take it to mean the Swiss Army knife approach, it means something like:
useful, especially through being able to perform several functions.
Yep, that sounds about right – several functions. So this Utility class can perform several functions. And sure enough, it does.
Except this causes the key and rather core issue with the whole Utility paradigm; it doesn’t fit with Object Orientated Programming;
Objects should do One Thing, and One Thing Well.
A Utils class doesn’t do One Thing, and over time, it certainly won’t do them “well”.
Over time, the humble Utils class that was a small collection of methods will grow into a dumping ground of functions that don’t really “fit” anywhere. This humble well meaning class is now spread all over the codebase, across multiple classes, and has many tests with lots of setup required due to its Utility nature. Refactoring this class is a pain, due to its many uses throughout the code.
I guess it would be unfair to ignore how these come into existence; I believe it to be the work of DRY (Don’t Repeat Yourself). This acronym is drilled into every developers brain right from the get go – move common code into a method, or into its own class to make it reusable and extendable. This is still very true – don’t recreate Property six times across your codebase without explicit reason to. But weird little methods like getPostcodeFromAddress() don’t really feel like they belong anywhere, but could be reused. So, where do we put them? And so the Utils Class is born.
Well, how do we avoid writing them? I’ve got quite a radical idea; just don’t write them.
Not writing utils classes takes a bit of getting used to, but in essence it goes something like this:
You have a method that doesn’t fit anywhere, let’s call it getRatioOfBedsToToilets(). What do you do? Well, I ask some questions to myself to see where it could go;
- Is this method actually only used once?
Why bother extracting something if it’s only being used once? Leave it as a private method in the class. Premature optimisation can cause lots of pain for very little gain
- Does it fit within the object it’s operating on?
In true OO style, could the method be put on the object? Should the Property object own this method?
- Could this fit with an existing class that’s specific in its domain?
There might already be a class that handles Property and ratios. So why not add it to that?
- Is there enough functionality here that it could be its own service?
Is this a business domain that contains enough logic to be broken into a Microservice (if you’re using Microservices that is!)*
Most code fits into one of the above. If it doesn’t, then it might fall into the well known category of a Library.
*Breaking common code down across services is a whole different topic, and one to be thought about. There are many concerns here such as what your infrastructure is like, what are your SLA’s, is this a domain / business specific concern, and how often the code changes. While I won’t go into it here, I will state one thing – do not build cross service libraries that store business domain. Instead, recreate the code per service, or extract out into its own service. More on this in another blog later on
We’ve all used libraries. They are generic, not business specific code. Think StringUtils, or Commons Collections. These project contains additions to the core language to make life easier. But, importantly, they are business agnostic. They have functions and methods that aren’t particular to any one businesses usecase. These libraries are shared the world over, to make everyone’s codebase a little cleaner. It also provides shared confidence – I can trust the Apache StringUtils library to be well tested and to have the backing of thousands of projects and developers.
So, if you find yourself writing code that’s generic and could be used in any project outside of your business, i.e. doesn’t contain business concerns, then this can and should be extracted out into it’s own library. And maybe even Open Sourced!
So what’s the TL;DR of this? Think about your code; is it business code, or is it a something that’s business agnostic?
If it’s business code; break it down and find similar concerns and put them together with an appropriate name. Give that Class a purpose.
If it’s generic functionality that could be shared externally of the project or business (think StringUtils), then break the code out and share it as a library.
But above all else: stop making utils classes.