When to use a Constructor and when to use getInstance() method (static factory methods)?

Java

Java Problem Overview


  1. When and how should we use a constructor

     Foo bar = new Foo();
    
  2. And when and how should we use getInstance() (static factory methods)

     Foo bar = Foo.getInstance();
    

What is the difference between these two? I have always used a constructor, but when should I use getInstance() instead?

Java Solutions


Solution 1 - Java

Everybody seems to focus on singletons while I think that the question is actually about constructor vs static factory methods.

This is actually Item 1: Consider static factory methods instead of constructors of Effective Java by Joshua Bloch:

> ### Item 1: Consider static factory methods instead of constructors > > The normal way for a class to allow a > client to obtain an instance of itself > is to provide a public constructor. > There is another technique that should > be a part of every programmer’s > toolkit. A class can provide a public > static factory method, which is simply a static method that returns an > instance of the class. Here’s a simple > example from Boolean (the boxed > primitive class for the primitive type > boolean). This method translates a > boolean primitive value into a > Boolean object reference: > > public static Boolean valueOf(boolean b) { > return b ? Boolean.TRUE : Boolean.FALSE; > } > > Note that a static factory method is > not the same as the Factory Method > pattern from Design Patterns > [Gamma95, p. 107]. The static factory > method described in this item has no > direct equivalent in Design > Patterns. > > > A class can provide its clients with > static factory methods instead of, or > in addition to, constructors. > Providing a static factory method > instead of a public constructor has > both advantages and disadvantages.

Advantages (quoting the book):

  • One advantage of static factory methods is that, unlike constructors, they have names.
  • A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.
  • A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.
  • A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances.

Disadvantages (still quoting the book):

  • The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.

  • A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.

Solution 2 - Java

You've got two questions: when should I call a getInstance() method, and when should I create one?

If you're deciding whether to call a getInstance() method, it's easy. You just need to read the class documentation to find out when you should call it. For example, NumberFormat provides a constructor and a getInstance() method; the getInstance() method will give you a localized NumberFormat. For Calendar, on the other hand, the constructor is protected. You have to call getInstance() to get one.

If you're deciding whether to create a getInstance() method, 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).


Long story short? Don't worry about creating getInstance() methods in your own code. If the time arises when they'll be useful, you'll know. And in general, if you can call a class's constructor, you're probably supposed to be doing that, even if the class provides a getInstance() method.

Solution 3 - Java

The uses for getInstance methods:

But most of the time your object will be a simple POJO and usage of public constructors is most practical and obvious solution.

U1: getInstance From Another Class

To return an instance of a different class:

public class FooFactory {
    public static Foo getInstance() {
        return new Foo();
    }
}

NumberFormat.getInstance methods do this as they actually return instances of DecimalFormat.

U2: Singleton Problems

The singleton pattern restricts many of the benefits of object oriented programming. Singletons generally have private constructors, therefore you cannot extend them. As you will be accessing it via its getInstance method and not referencing any interface, you will not be able to swap it out for another implementation.

Solution 4 - Java

If you can use both then it sound like a poorly implemented singleton pattern.

Use the second option if you intend to have only one single instance of the class in your system and make the constructor private then.

Use the first to allow building several objects of the class.

BUT do not give your class the both possibilities.

Take care not to over-use singletons, only use them if really only one instance shall exist in the system otherwise you would limit the possibilities of re-use of your class in other projects. It sounds interesting to be able to call getInstance from everywhere in your project but that makes unclear who actually owns that instance: nobody and/or all. If you have a lot of singletons in a project you can bet that the system is poorly designed (usually). Singletons should be used with care, the same advice than for global variables apply.

Solution 5 - Java

One case in which I always prefer a static factory over a regular constructor is when I know the object construction will be slowish. I do simple initialization on constructor, but if I need to create something heavy I'll use a static method and document the behavior.

Solution 6 - Java

Singletons are evil. The problems I've seen surrounding it are not about re-use or extendability of a system (although I could see how that could occur), more so that I can't count the number of times i've seen obscure bugs in a system that arise from singletons.

If you do need to use a singleton, ensure it's scope is extremely narrow, i.e. judiciously limit the number of other objects in your system that know about it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionzengrView Question on Stackoverflow
Solution 1 - JavaPascal ThiventView Answer on Stackoverflow
Solution 2 - JavaChris B.View Answer on Stackoverflow
Solution 3 - JavakrockView Answer on Stackoverflow
Solution 4 - JavajdehaanView Answer on Stackoverflow
Solution 5 - JavaGuuView Answer on Stackoverflow
Solution 6 - JavarupjonesView Answer on Stackoverflow