What is Static Factory Method

  1. static factory method pattern is a way to encapsulate object creation.This prevents unnecessary object creation through constructors
  2. The constructors are marked private, so they cannot be called except from inside the class, and the factory method is marked as static so that it can be called without first having an object.

Examples

  1. Limit the No of Instances to be Created – If the construction and destruction are expensive processes it might make more sense to build them once and recycle them. The factory method can return an existing, unused instantiated object if it has one, or construct one if the object count is below some lower threshold, or throw an exception or return null if it’s above the upper threshold.
  2. We can provide a meaningful name for our constructors

RandomIntGenerator.java

public class RandomIntGenerator {
  private final int min;
  private final int max;

  private RandomIntGenerator(int min, int max) {
    this.min = min;
    this.max = max;
  }

  public static RandomIntGenerator between(int max, int min) {
    return new RandomIntGenerator(min, max);
  }

  public static RandomIntGenerator biggerThan(int min) {
    return new RandomIntGenerator(min, Integer.MAX_VALUE);
  }

  public static RandomIntGenerator smallerThan(int max) {
    return new RandomIntGenerator(Integer.MIN_VALUE, max);
  }

  public int next() {...}
}
Foo x = new Foo() 

With this pattern, you would instead call the factory method:

Foo x = Foo.create()

The constructors are marked private, so they cannot be called except from inside the class, and the factory method is marked as static so that it can be called without first having an object.

When to use Static Factory Method
1.One is that the factory can choose from many subclasses (or implementers of an interface) and return that. This way the caller can specify the behavior desired via parameters, without having to know or understand a potentially complex class hierarchy.

2.Controlling access to a limited resource such as connections. This a way to implement pools of reusable objects – instead of building, using, and tearing down an object, if the construction and destruction are expensive processes it might make more sense to build them once and recycle them. The factory method can return an existing, unused instantiated object if it has one, or construct one if the object count is below some lower threshold, or throw an exception or return null if it’s above the upper threshold.

3.Alternate to constructor overloading.

Example1 – Returning Object of many Subclass as per parameter

class Employee {
   private int empType;
   static final int ENGINEER = 0;
   static final int SALESMAN = 1;
   static final int MANAGER = 2;

   Employee (int type) {
       empType = type;
   }

I want to make subclasses of Employee to correspond to the type codes. So I need to create a factory method

static Employee create(int type) {
      return new Employee(type);
 }

I then change all callers of the constructor to use this new method and make the constructor private

client code...
   Employee eng = Employee.create(Employee.ENGINEER);

 class Employee...
   private Employee (int type) {
      empType = type;
}

So far I dont have any advantage from the code.The advantage come when I code the create method to return instances of different subclass of Employee.

static Employee create(int type) {
       switch (type) {
           case ENGINEER:
              return new Engineer();
           case SALESMAN:
              return new Salesman();
           case MANAGER:
              return new Manager();
           default:
              throw new IllegalArgumentException("Incorrect type code value");
       }
   }  

If you want to avoid making changes in the switch when ever new classes are added the above code can be replaced as below

static Employee create (String name) {
       try {
           return (Employee) Class.forName(name).newInstance();
       } catch (Exception e) {
           throw new IllegalArgumentException ("Unable to instantiate" + name);
       }
}

Now the calling class should be

 Employee.create("Engineer")

Example2 – Controlling access to Resources

public class DbConnection
{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection()
   {
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection()
   {
     if(totalConnections < MAX_CONNS)
     {
       return new DbConnection();
     }

     else if(availableConnections.size() > 0)
     {
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;
     }

     else {
       throw new NoDbConnections();
     }
   }

   public static void returnDbConnection(DbConnection dbc)
   {
     availableConnections.add(dbc);
     //...
   }
}
  1. The maximum connection allowed in the above case is 100
  2. Incase the no of connection created is above 100, Old connection is sent back in else part of code

Example3 – Alternate to Constructor Overloading
Link

Comments are closed.