Java Util Calendar – Why Use Static Factory Methods?

Architecturedesign-patterns

It is considered better to have a separate factory class than having static methods in same class. See this question.

But the standard API uses both approaches.

Separate factory:

DatatypeFactory.newInstance().newXMLGregorianCalendar(...)

Static methods in same class:

Calendar.getInstance(...)

Why is this? In what case would having static methods be better than having a separate factory?

Best Answer

Factory is probably one of the most misused patterns. People always talk about how it allows to easily switch to a different factory that generates different classes, but usually fail to notice that you can't do that with factory alone - you need some sort of dependency injection too!

The overhead seems small - use CalendarFactory.newInstance().newCalendar() instead of Calendar.getInstance(). But we wanted factory in the first place so we could easily switch factories and change the way objects are constructed. Can we really do that here? CalendarFactory.newInstance() is always the same function so it'll always return a factory object constructed the same way, which will create Calendars in the same way. In order to change the Calendar creation process, we need to either change CalendarFactory.newInstace or CalendarFactory.newCalendar. How is that any better from having to change Calendar.getInstance?

If we want to be able to easily change the Calendar creation process, we had to use dependency injection - create a CalendarFactory object somewhere and pass it around. That way we can control which factory the methods we call and objects we construct use.

There is a drawback to this approach though - having to pass that factory object around introduces quite a burden on the programmer. Methods need an extra arguments - for the entire call-chain from where the factory is created to where it's used. Objects need an extra field that you need to supply even if you don't use any method that requires that factory(alternatively - you have to remember if you supplied it or not, and exception will be thrown if the factory field is not set. But this exposes the implementation as it forces the user to know which methods require setting the factory field).

Since the overhead here is much bigger than the naive, worthless use of the factory, we can't just blindly apply the pattern(OK, I take that back - you can always blindly apply design patterns, and too many programmers do) and we actually need to think. Do we really need to be able to switch the Calendar creation process all over the place? Do we need it enough to introduce such burden on the programmers?

In the case of Java's Calendar, the answer was "no". Being able to tell what the time is differently, or to represent it differently in the memory, is not useful enough to have to pass around a CalendarFactory object all over the place.