I would disagree with the generally accepted wisdom that utility classes should be avoided. Using Java here as an example, but I'm sure the idea applies to other languages as well.
Consider, for example, a data type of which you need both mutable (for performance) and immutable (for hash table keys, sets, other kinds of correctness problems, etc.) variants: a complex number. So, you have Complex
(immutable) and ComplexBuffer
(mutable). Now it would be foolish to write four versions of the subtraction fuctionality (Complex
- Complex
, ComplexBuffer
- Complex
, Complex
- ComplexBuffer
, ComplexBuffer
- ComplexBuffer
), so you will want to create a common interface ComplexNumber
shared by Complex
and ComplexBuffer
. The ComplexNumber
interface has getReal()
and getImag()
methods.
Now, to subtract two ComplexNumber
implementing objects, you will define a class ComplexUtils
and a static method public static Complex sub(ComplexNumber, ComplexNumber)
. So, there you have it: a problem where the best solution is to actually use a utility class. Of course, for performance you will have also ComplexBuffer.subInPlace(ComplexNumber)
that creates absolutely no new objects.
So, don't follow blindly the advice that utility classes should be avoided. As John Carmack has said:
Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.