25

I am often confrontated with helper or util classes in Java or whatever kind of language. So I was asking myself if this is some kind of Anti Pattern and the existence of these kind of classes is just a lack of missings in the design and architecture of a Software.

Often these classes are confined using just static methods, which do a lot of things. But mostly it is indeed context dependent and statefull.

My question is, what is your opinion about such kind of static helper/util classes because the advantage is of course the fast invocation using just the class name.

And at what kind of abstraction level you would avoid using these kind of classes?

In my opinion the keyword "static" should just be allowed within the declaration of a class (Java) and not for methods. In my opinion is that using it at this way, it could be a good alternative and middleway to be able to combine Procuedural- and OO-Paradigms in Java and avoid missuse of the keyword.

Additions due to the answers:

At first I think that it is completely legal to be able to combine different paradigms and even use runtime interpreted scripting languages within machine or vm compiled code.

My experience is that during the development process of a project such kind of helpers and utils or whatever the name is, are growing and growing and used within every forgotten corner of the codebase, which was originally designed to be modular and flexibel. And due to a lack of time to make refactorings or think about the design again you just make it much worse over the time.

I think static should be removed from Java. Especially now where it is possible to use even more sophisticated functional language elements.

Diversity
  • 359

5 Answers5

23

Well, Java lacks free functions, thus you are forced to put them as static functions into some pro-forma class. A necessary work-around is never an anti-pattern, though it might lack elegance.

Next, there's nothing wrong with free functions. Actually, using free functions reduces coupling, as they only have access to the public interface instead of all the gory details.

Of course, using free/static functions does not in any way alleviate the dangers of mutable shared, especially global, state.

Deduplicator
  • 9,209
21

Static utility or helper functions are not an anti pattern if they adhere to some guidelines:

  1. They should be free from side effects

  2. They are used for application specific behavior that does not belong in the class or classes on which these functions operate

  3. They do not require any shared state

Common use cases:

  • Formatting dates in an application specific way
  • Functions that take one type as input and return a different type.

For example in an application I worked on users keep journal entries for their activities. They can specify a follow-up date and download an event reminder. We created a static utility class to take a journal entry and return the raw text for a .ics file.

It didn't require any shared state. It didn't mutate any state, and creating an iCal event certainly was application specific and didn't belong in the journal entry class.

If the static functions or utility classes have side effects or require shared state I would recommend reevaluating this code, as it does introduce coupling that can be difficult to mock for unit testing.

4

It will depend on your approach. Many applications are written with a more functional, as opposed to classical mindset (including much of the suite of sites you are on).

With this mindset, there will be many utility methods on worker classes that can be strung together as static methods. They are fed/use closer to plain objects that only hold data and get passed around.

It's a valid approach and can work very well, especially at scale.

Tracker1
  • 314
2

I personally think the only important part about such helper classes is that they be made private. Besides that - they are strictly a good idea (applied sparingly).

The way I think about this - is if in implementing a class (or function) - something like this is helpful, and makes that implementation clearer, how could that be bad? And OFTEN its critical to define such private helper classes to allow integration with and use of other algorithms which depend on data being in a particular shape.

Whether to label it 'helper' is a small matter of personal taste, but it connotes that it helps in implementation and its of no interest/use to a wider audience. If that's what makes sense - go for it!

Lewis Pringle
  • 2,975
  • 1
  • 11
  • 15
2

The prevalence of static helper classes in based on a misconception. Just because we call classes with only static methods "utility classes" does not mean that it is not allowed to write common behavior in POJOs.

static helper classes are anti pattern for three reasons:

  1. The static access to this helper methods hides dependencies. If these "utility classes" were POJOs you could inject them int to a dependent class as constructor parameters which would make the dependency obvious for any user of a dependent class.

  2. The static access to this helper methods cause tight coupling. This means that the code using the helper methods is hard to reuse and (as a side effect) hart to test.

  3. Especially if they maintain state these are merely global variables. And hopefully nobody argues that global variables are any good...

Static helper classes are part of the STUPID code anti pattern.


Global state is unrelated to the question, – max630

The OP wrote:

But mostly it is indeed context dependent and statefull.

Static statefull constructs are global states.

any kind of code can use it. – max630

Yes, of cause. And almost all applications need some kind of global state.

But global state != global variable.

You can create global state with OO techniques via dependency injection But you cannot avoid global state with statefull static structures which are global variables at the bottom.