For the past decade or so, I've been using the pattern below for my Java utility classes. The class contains only static methods and fields, is declared final
so it can't be extended, and has a private
constructor so it can't be instantiated.
public final class SomeUtilityClass {
public static final String SOME_CONSTANT = "Some constant";
private SomeUtilityClass() {}
public static Object someUtilityMethod(Object someParameter) {
/* ... */
return null;
}
}
Now, with the introduction of static methods in interfaces in Java 8, I lately find myself using a utility interface pattern:
public interface SomeUtilityInterface {
String SOME_CONSTANT = "Some constant";
static Object someUtilityMethod(Object someParameter) {
/* ... */
return null;
}
}
This allows me to get rid of the constructor, and a lot of keywords (public
, static
, final
) that are implicit in interfaces.
Are there any downsides to this approach? Are there any benefits to using a utility class over a utility interface?
Going based on the person who coined the Constant Interface pattern an anti-pattern, I would say although you don't intend the client(s) to implement the interface, it's still possible, possibly easier, and shouldn't be allowed:
Although as mentioned below, it really depends on the target audience
A lot of easy-to-use designs patterns get a lot of criticism (Context pattern, Singleton pattern, Constant Interface pattern). Heck, even design principles such as the law of demeter gets criticised for being too verbose.
I'd hate to say it, but these kinds of decisions are opinion based. Although the context pattern is seen as an anti-pattern, it's apparent in mainstream frameworks such as Spring and the Android SDK. It boils down to the environment, as well as target audience.
The main downside that I can find is listed as the third listing under "downsides" in the Constant Interface wiki:
If you ever figure "Hey, this actually isn't a contract and I want to enforce stronger design", you will not be able to change it. But as I've said, it's up to you; maybe you won't care to change it in the future.
On top of that, code clarity as mentioned by @TagirValeev. Interfaces have the intent of being implemented; if you don't want someone to implement the API you're supplying, don't make it implementable. But I believe this revolves around the "target audience" statement. Not gonna lie, I'm with you on the less-verbose foundation, but it depends on who my code is for; wouldn't wanna use a constant interface for code that may get reviewed.