1

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?

7
  • 1
    you are confusing a factory with the singleton.
    – amon
    Jan 22, 2014 at 11:15
  • 1
    @amon Not really. Calendar in this example is not a singleton. Jan 22, 2014 at 11:26
  • 3
    Oh, you're right. Then: that classes designer is confusing a factory with the singleton ;-)
    – amon
    Jan 22, 2014 at 11:34
  • 3
    I can't remember who said it, but... java.util.Date is a great example of how even brilliant programmers can screw up. java.util.Calendar is a testament to the fact that average programmers can screw up too.
    – Phoshi
    Jan 22, 2014 at 11:59
  • Considered by who? I see no problem with static factory methods - they are almost always better than constructors, you can read the list of benefits in Bloch's Effective Java. Declaring one proven thing to be universally better than another is an end of career for a system architect. Jan 23, 2014 at 4:48

2 Answers 2

1

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.

2
  • Factory != abstract factory
    – Basilevs
    Jan 23, 2014 at 18:10
  • @Basilevs This distinction is irrelevant here. It doesn't matter for this discussion if the base factory type is a concrete class, an abstract class or an interface - the question here is how one obtains the factory object, not how it's defined.
    – Idan Arye
    Jan 24, 2014 at 2:51
0

It's not a singleton (I've been living a lie...). Now it does seem like poor naming convention.

Seems like the Java conevtion for a singleton getInstance(), is ClassName.getClassName()

You can see it in Desktop.getDesktop() (java.awt).

The getInstance() belongs to factory patterns, which means that Calendar is a factory.

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#getInstance()

Factory methods usually start with newXYZ() while a singleton usually has the getinstance() method.

In your example, DataTypeFactory is, in fact, a factory.

On the other hand, Calendar is a singleton, and as such it has a getInstance() method.

2
  • Are you sure Calendar is a singleton? System.out.println(Calendar.getInstance() == Calendar.getInstance()) prints false. Jan 22, 2014 at 11:25
  • You're right. it isn't, I'll remove my answer. You can see the Java documentation to see how it works, the getInstance() initializes a calendar. Jan 22, 2014 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.