jobs4timesLogo jobs4timesLogo

Factory Design Pattern

  • Not all objects in the java can be created out of new operator. Few objects may be created out of view; few may have to be created by calling a static factory method on the class(singleton) others may have to be created by passing other object as reference while creating etc.

  • If I want a car, do I need to know how to create a car ? If I try to manufacture my own car, it takes ages to complete it. Instead I can go to a factory that is proficient in manufacturing car to get a car.

  • The main advantage of going for factories is it abstracts the creational process of other class. For e.g let's take an example of Jdbc, Connection is an interface in jdbc api, respective vendor driver will have the implementation of Connection interface. Oracle driver will provide an implementation class for Connection interface and MS Sql server will provides its own implementation for Connection interface.

  • If we try to create an Object of Connection interface, can we find what is the implementation class for the Connection interface provided by that vendor and can instantiate ? Practically if will not be possible for us to remember various vendor provided implementation class names.

  • So, jdbc has provided an factory class called DriverManager, instead of we finding the implementation class for Connection interface, if we go to DriverManager and call a method getConnection(), he will takes care of finding the implementation class based on url we provided and instantiates the appropriate vendor implementation of Connection interface.

  • In the above case we are subtracted from creation on Connection implementation object rather if we just go to DriverManager and call the getConnection() method he takes care of creating the implementation of connection object, this is the main advantage of going for factories.

  • Every factory class has a method; it contains the logic for creating the object of another class, so it is called factory method. Generally these methods will be declared as static to let you call without creating the object of factory.

An UML representation of Factory pattern :
factory-pattern

package design;

public interface Pizza{
	void prepare();
	void bake();
	void cut();
}
In the shop we sell various types of Pizza's like CheesePizza and ChickenPizza etc., So, we have several sub-classes from Pizza class to sell different types of pizza.
package design;

public class CheesePizza implements Pizza{

@Override
public void prepare() {
 System.out.println("preparing cheese pizza...");
}

@Override
public void bake() {
 System.out.println("baking cheese pizza...");
}

@Override
public void cut() {
 System.out.println("cutting cheese pizza...");
}
	
}
package design;

public class ChickenPizza implements Pizza{

@Override
public void prepare() {
 System.out.println("prepare chicken pizza...");
}

@Override
public void bake() {
	System.out.println("baking chicken pizza...");
}

@Override
public void cut() {
	System.out.println("cutting chicken pizza...");
}
	
}
Now in the PizzaStore class if someone orders a Pizza we need to check which type of pizza and needs to create it.
package design;

public class PizzaStore{
public Pizza orderPizza(String type){
 Pizza p=null;
 if(type.equals("cheese")){
  p=new CheesePizza();
 }else if(type.equals("chicken")){
  p=new ChickenPizza();
 }
 p.prepare();
 p.bake();
 p.cut();
 
 return p;
 
}
}
  • Now demand for adding more pizza types came and we add TomatoPizza, CornPizza. Again we need to modify the code inside the orderPizza() method of PizzaStore to add or remove more pizza types, which involves the modify the code in PizzaStore class.

  • May be some other classes in our application also want create a pizza, so the above piece of logic has to be written in another class. Apart from this if PizzaStore has to sell pizza it needs to know the implementation class of all Pizza types and how to instantiate them as well. Is there any better way handling this ?

  • Yes, that's where factory comes into picture. Instead of writing the logic for creating various types of pizza's in PizzaStore we can separate it and write in a factory class called PizzaFactory. Now if PizzaStore wants a pizza, it doesn't need to know which is the implementation class for creating a pizza rather it can call a factory method on the PizzaFactory class to get a pizza.

package design;

public class PizzaFactory {

public static Pizza cteratePizza(String type) { 
 Pizza p=null;
 
 if(type.equals("cheese")){
  p=new CheesePizza();
 }else if(type.equals("chicken")){
  p=new ChickenPizza();
 }
 
 return p;
}

}
Modified PizzaStore
package design;

public class PizzaStore{
public Pizza orderPizza(String type){
 Pizza p=null;
 
 p=PizzaFactory.cteratePizza(type);
  //call factory method to get the pizza
 p.prepare();
 p.bake();
 p.cut();
 
 return p;
 
}
}
In the above we are able to abstract to abstract the creation of pizza from PizzaStore, without knowing how to create a pizza, PizzaStote can sell the pizza easily.


BACK