70

Let's say I have a utility class DateUtil (see below). To use this method a caller method uses DateUtils.getDateAsString(aDate). Would it be better to remove the static modifier and make DateUtil a spring bean (see DateUtilsBean) and inject it into calling classes or just leave it as is?

One disadvantage I can see with using static is issues around mocking, see How to mock with static methods?

public class DateUtils {

    public static String getDateAsString(Date date) {       
        String retValue =  "" // do something here using date parameter
        return retValue;
    }
}

Spring Bean version

@Component
public class DateUtilsBean {

    public String getDateAsString(Date date) {      
        String retValue =  "" // do something here using date parameter
        return retValue;
    }
}
Community
  • 1
  • 1

3 Answers3

47

I don't think so. A DateUtils class sounds like a pure utility class that doesn't have any side effects but just processes input parameters. That kind of functionality may as well remain in a static method. I don't think it's very likely that you'll want to mock date helper methods.

Sean Patrick Floyd
  • 284,665
  • 62
  • 456
  • 576
  • 14
    Agreed. Just because _anything_ _could_ be wired as a Spring bean doesn't mean _everything_ _should_ be wired as a Spring bean. – David J. Liszewski Sep 01 '11 at 13:37
  • 7
    what if the static method reads a configuration file that drives my application? that is likely that I want to mock that behavior. Just think of it: you want to do functional testing but you don't want to become a "configuration factory". if it would be a singleton then I can more easily mock that method and drive my test from code. However it's possible with PowerMock to mock static methods too. – uthomas Sep 22 '11 at 07:24
  • 5
    It could be over-engineering, but making it a bean that can be injected makes it easier to unit-test dependent classes. It would make it even easier to test if it had implemented an interface. – Behrang Dec 12 '12 at 00:41
  • 1
    An important use case is time. Consider using Java 8's Clock as a bean to avoid flaky tests related to time. – David W Nov 27 '18 at 14:44
  • @DavidW true, but that Clock was specifically designed for that purpose. I've used it when editing other people's code, but I'd still prefer to make my methods idempotent, so I'd pass in Dates from the outside. – Sean Patrick Floyd Nov 27 '18 at 22:16
29

I agree with Sean Patrick Floyd.

This is my criterion: if the methods of the class do things only over the parameters they receive, with no external dependencies (database, file system, user config, other objects/beans, etc.), then I would do it with static methods, usually in a final class with a private constructor.

Otherwise, I would implement it using a Spring bean.

So, in the case that you raise, according to this criterion, I would write a class with static methods.

Regards.

Alberthoven
  • 2,688
  • 1
  • 23
  • 26
17

It would be better to declare it as a Spring bean because the life cycle of it is then managed by Spring, and you can eventually inject dependencies, pool the object, as well as test it in a proper way, not to talk that you could use it as a regular object and pass it as parameter, redefine the method in subclasses... etc.

In short, yes it would be a better design in most cases. Nevertheless, in a case as simple as the exposed, it doesn't do a great difference.

Mr.Eddart
  • 9,630
  • 11
  • 46
  • 74