A few of us were chatting about static methods the other day.
I’m not a big fan. I think that they tie you unnecessarily to a concrete class.
Most people were saying that there is no harm in having static methods in utility classes, and this is one place where I would disagree.
The example used was the java.lang.Math class with it’s utility methods.
java.lang.Math is non-instantiable, you can only access it’s utility methods through static calls.
For the most part, this is fine, but take the example of Math.sqrt(x)
This method returns NaN if x is < 0. For the majority of cases this is fine, but if I start working with complex numbers, then this is no longer the ideal behaviour.
Admittedly, in this case I would not want the return value to be a double, but I may want it to throw a ComplexNumberException or something similar. If I have used the static method throughout my code, I now have to go and update every single reference to the concrete class. What a pain in the class!
However, if I had used a utility class with instance methods, I could have injected the utility class in the constructor and I could now change it out for my new ComplexMathUtility class through configuration / DI.
This isn’t the best example, as the required return types are different, but think of a String utility class, perhaps something that formats a header for a report.
We could (naively) implement this using static utility methods. If we later require two different types of report heading, this is going to make our life difficult.
If we implement this using an instantiable ReportFormatter, we can swap in new ones at runtime / configuration. We’ve just implemented a ReportFormatterStrategy
My feeling is that implementing utilities as instance methods keeps the design flexible and allows for more code reuse as things naturally gravitate towards smaller, more easily testable, logically grouped units of functionality…
Or am I just dreaming?