Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do we ever need to prefer constructors over static factory methods? If so, when?

I have been reading Effective Java by Joshua Bloch and so far it really lives up to its reputation. The very first item makes a convincing case for static factory methods over constructors. So much that I began to question the validity of the good old constructors :).

The advantages/disadvantages from the book are summarized below:

Advantages:

  1. They have names!
  2. We have total instance control (Singletons, performance, etc.)
  3. They can return a subtype/interface
  4. Compiler can provide type inference

Disadvantages:

  1. Private classes cannot be subclassed
  2. They do not stand out in the documentation as constructors do

The first disadvantage can actually be A Good Thing (as mentioned in the book). The second one, I think is just a minor disadvantage and can be resolved easily with the upcoming java releases (annotations for javadoc etc.)

It looks like, in the end factory methods have almost all the advantages of constructors, many many more advantages, and no real disadvantages !

So, my question is basically in three parts:

  1. Is it good practice to always use static factory methods by default over constructors?
  2. Is it ever justified to use constructors?
  3. Why don't object-oriented languages provide language level support for factories?

Note: There are two similar questions: When to use a Constructor and when to use getInstance() method (static factory methods)? and Creation of Objects: Constructors or Static Factory Methods. However the answers either just provide the above list or reiterate the rationale behind static factory methods which I am already aware of.

like image 992
Cagil Seker Avatar asked Mar 09 '12 15:03

Cagil Seker


3 Answers

static factories still have to call a constructor in the end. You can move most of the functionality into the static factory, but you cannot avoid using a constructor.

On the other hand for simple cases, you can have just a constructor without having a static factory.

Constructors are the only way to set final fields, which IMHO are preferable to non-final fields.

You can use constructors can in sub-classes. You cannot use static factories for a sub-class.

If you have a good dependency injection framework to build dependencies of a component, you may find that static factories don't add much.

like image 50
Peter Lawrey Avatar answered Nov 06 '22 22:11

Peter Lawrey


I like the comment from one of the similar questions you highlighted:

(On how to decide if you should favour a factory method over a constructor),

"you need to decide what you're trying to accomplish. Either you don't want people to call your constructor (you're creating a singleton or a factory), or you don't mind (as in NumberFormat above, where they're initializing some objects for the convenience of the caller)"

To me, this means it is justified to use a constructor, where the factory method is not required. Without any need for a factory, it just makes the code harder to follow ("which exact sub-class is returned here?")

like image 32
matt freake Avatar answered Nov 06 '22 21:11

matt freake


I'm in pretty strong agreement with Josh Bloch here, and he makes the case better than I could, but here are a few places where static factories aren't as appropriate:

  • When dependency injection is more sensible; DI systems (certainly Guice) tend to inject things through their constructors. In particular, DI is appropriate when you expect that the parameters of the constructor might change in the future.
  • When you specifically intend for people to write subclasses, and you're providing a skeleton for them to implement.
like image 38
Louis Wasserman Avatar answered Nov 06 '22 21:11

Louis Wasserman