Factory Design Pattern

Factory design pattern

Factory design pattern is one of the Creational design pattern. Factory design pattern is used when we have a super class with multiple sub-classes and based on input, we need to return one of the sub-class. This pattern take out the responsibility of instantiation of a class from client program to the factory class.

Super class

Super class in factory design pattern can be an interface, abstract class or a normal java class. In our example, we have abstract super class with overridden toString() method for testing purpose.

package com.ashok.designpatterns.model;

/**
 * 
 * @author ashok.mariyala
 *
 */
public abstract class MyComputer {  
   public abstract String getRAM();
   public abstract String getHDD();
   public abstract String getCPU();
   
   @Override
   public String toString(){
      return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
   }
}
Sub class

Let’s say we have two sub classes MyPersonalComputer and MyServer with below implementation.

package com.ashok.designpatterns.model;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyPersonalComputer extends MyComputer {
   private String ram;
   private String hdd;
   private String cpu;
   
   public MyPersonalComputer(String ram, String hdd, String cpu){
      this.ram = ram;
      this.hdd = hdd;
      this.cpu = cpu;
   }
   @Override
   public String getRAM() {
      return this.ram;
   }

   @Override
   public String getHDD() {
      return this.hdd;
   }

   @Override
   public String getCPU() {
      return this.cpu;
   }
}

Notice that both the classes are extending MyComputer super class.

package com.ashok.designpatterns.model;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyServer extends MyComputer {
   private String ram;
   private String hdd;
   private String cpu;
   
   public MyServer(String ram, String hdd, String cpu){
      this.ram=ram;
      this.hdd=hdd;
      this.cpu=cpu;
   }
   @Override
   public String getRAM() {
      return this.ram;
   }

   @Override
   public String getHDD() {
      return this.hdd;
   }

   @Override
   public String getCPU() {
      return this.cpu;
   }
}

Finally the factory class is

package com.ashok.designpatterns.factory;

import com.ashok.designpatterns.model.MyComputer;
import com.ashok.designpatterns.model.MyPersonalComputer;
import com.ashok.designpatterns.model.MyServer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyComputerFactory {
   public static MyComputer getComputer(String type, String ram, String hdd, String cpu){
      if("MyPersonalComputer".equalsIgnoreCase(type)) 
         return new MyPersonalComputer(ram, hdd, cpu);
      else if("MyServer".equalsIgnoreCase(type)) 
         return new MyServer(ram, hdd, cpu);
      return null;
   }
}

Note

  1. We can keep Factory class Singleton or we can keep the method that returns the subclass as static.
  2. Notice that based on the input parameter, different subclass is created and returned. getComputer is the factory method.

Now, simple test client program that uses above factory design pattern implementation is as follows,

package com.ashok.designpatterns.test;

import com.ashok.designpatterns.factory.PCFactory;
import com.ashok.designpatterns.factory.MyComputerFactory;
import com.ashok.designpatterns.model.MyComputer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyTestFactory {
   public static void main(String[] args) {
      MyComputer pc = MyComputerFactory.getComputer("PersonalComputer","4 GB","500 GB","2.6 GHz");
      MyComputer server = MyComputerFactory.getComputer("MyServer","16 GB","1 TB","2.9 GHz");
      System.out.println("Factory PC Configuration is : " +pc);
      System.out.println("Factory Server Configuration is : " +server);
   }
}

Output
Factory PC Configuration is : RAM= 4 GB, HDD=500 GB, CPU=2.6 GHz
Factory Server Configuration is : RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
Factory Design Pattern
Scroll to top