CaitlinG
CaitlinG

Reputation: 2015

Object instantiation with a Factory Method

I am currently enrolled in a CS2 course (data structures) where Java is the language used and I am interested in comparing and contrasting object instantiation using the traditional constructor method v.s. a factory method. Does one represent a greater degree of computing elegance than the other? Would a factory method handle parameters in a manner similar to a parameterized constructor? E.g:

public class Tester
{
    private String name;
    private int age;

    // Parameterized constructor  
    public Tester(String myName, int myAge)
    {
        this.name = myName;
        this.age = myAge; 
    }
} 

Essentially, I'm very curious on how one would write an equivalent factory method and what the potential benefits would be of doing so.

Thanks,

~Caitlin

Upvotes: 3

Views: 2706

Answers (3)

Hot Licks
Hot Licks

Reputation: 47729

A factory is useful in specific situations:

  1. Where one of several different subclasses of the object might be returned, based on parameters.
  2. Where there is some need to "guard" the creation of objects, perhaps for security, perhaps for some sort of synchronization.
  3. Where created objects need to be "enrolled" somehow after creation, and doing so in the constructor is not feasible.
  4. Where one does not even want to load the (actual) class (and it's tree of referenced classes) unless an instance must be created.

Where some reason such as the above is not present, there is no benefit to factory methods, and they simply obscure the logic.

There is no real restriction on what a factory can do, given that it can (if things are set up properly) access package level constructors and interfaces that are not accessible to the hoi polloi.

Added: To address the "inheritance" issue --

Let's say we have the classical Vehicle example, with Car and Truck subclasses. If you simply have CarFactory and TruckFactory then that increases the complexity of the code for no good reason (unless there are other compelling reasons for using factories).

But you can have a VehicleFactory and have it "decide", based on input or external factors, to create a Car or a Truck. This is a fairly common pattern.

However, if you were to (for some reason) have a VehicleFactory that only created Vehicle objects (not Cars or Trucks), and if use of the factory were mandatory (you couldn't access Vehicle's constructors), that would make it essentially impossible to subclass Vehicle. When you use a factory you make it very difficult (at the least) for someone else to add new subclasses.

Upvotes: 2

scottb
scottb

Reputation: 10084

According to the well-reasoned observations in Effective Java, the main advantages to static factory methods are as follows:

  • You can name them, unlike constructors which must always be named after the class. This makes code more readable and can avoid ugly situations where overloaded constructors might be impossible due to the types of arguments being the same, etc. In such a case, you could easily supply two factory methods with different names that indicate the difference.

  • A static factory method is not required to actually instaniate anything unlike a constructor which must create a new instance. Static factory methods are therefore essential for classes that are instance-controlled (eg. singleton classes).

  • Unlike constructors, a static factory method can return any object at all as long as the returned object matches or is a subclass of the return type. This enables interface-based type systems. The Enum framework of Java 1.5 makes use of this: the EnumSet class has no public constructors, only static factories. The actual object that is returned by the static factories varies depending on the size of the enum.

The main disadvantage of static factories is that they cannot be the basis of a class designed for inheritance. A class that provides only private constructors cannot be subclassed. A minor disadvantage of static factory methods is that they cannot be distinguished from other static methods, and so in order for them to be recognizable to the reader they usually follow naming patterns (they can be annotated if such a one is designed as a marker annotation for static factory methods).

Upvotes: 2

nanofarad
nanofarad

Reputation: 41281

Factory methods are nice as they can return a reference to an object that isn't necessarily an instance of that class. It can return that class, a subtype, or even null, and generally carry themselves on any way they want that a method can. You can thus move logic of selecting types into your own code. You can return an existing instance where appropriate, saving heap space and such.

Another basic pseudoexample is Integer.forValue() that can intern an integer, so identical immutable objects don't get recreated for no reason. Also see Executors.newXxxThreadPool().

A basic example:

public class Tester
{
    private String name;
    private int age;

    // Parameterized constructor  
    private Tester(String myName, int myAge)
    {
        this.name = myName;
        this.age = myAge; 
    }
    public static Tester getTester(String mn, int ag){
        if(age>0){return new Tester(mn, ag);}
        else if(age>80){return new OldPersonThatExtendsTester(mn, ag);} 
        //we'd need a public or otherwise accessible constructor above. It's a subtype!
        else {return null;} //yes, this is possible
    }
} 

Upvotes: 3

Related Questions