Factory Design Pattern With Example

In this article we will try to implement Factory Design pattern using an example of a knife factory which produces different types of knives like chef knife, bread knife etc.
 
Q. What is the Goal/Purpose of Factory Pattern with this analogy?
 
A. Just like a knife factory in the real world, the purpose of these factories in object-oriented programming is to create objects.
 
Q. When/Where we should use Factory Pattern?
 
A. Let's try to understand this scenario with our knife example.
 
Below i have implemented a method, orderKnife(){}, which takes string input of the type of knife to be created, creates that type of knife, then performs some common knife operations like sharpen(), polish() etc and returns back the knife object. Here we are using concrete instantiation. 
 
Concrete instantiation is the act of actually instantiating a class to create an object of a specific type. 
  1. Knife orderKnife(string knifetype)  
  2. {
  3.            Knife knife;  
  4.   
  5.            //create knife object using concrete instantiation  
  6.   
  7.            if (knifetype=="steak")  
  8.            {  
  9.                knife = new SteakKnife();  
  10.            }  
  11.            else if(knifetype=="chefs")  
  12.            {  
  13.                knife = new ChefsKnife();  
  14.            }  
  15.   
  16.            //prepare the knife  
  17.   
  18.            knife.sharpen();  
  19.            knife.polish();  
  20.            knife.package();  
  21.   
  22.            return knife;  
  23. }
Consider now If we have to add new types of knives,  then our if(){} elseif(){} condition keeps on growing: 
  1. Knife orderKnife(string knifetype)  
  2.   {  
  3.             Knife knife;  
  4.   
  5.             //create knife object using concrete instantiation  
  6.             if (knifetype=="steak")  
  7.             {  
  8.                 knife = new SteakKnife();  
  9.             }  
  10.             else if(knifetype=="chefs")  
  11.             {  
  12.                 knife = new ChefsKnife();  
  13.             }  
  14.             else if (knifetype == "bread")  
  15.             {  
  16.                 knife = new BreadKnife();  
  17.             }  
  18.             else if (knifetype == "paring")  
  19.             {  
  20.                 knife = new ParingKnife();  
  21.             }  
  22.   
  23.             //prepare the knife  
  24.             knife.sharpen();  
  25.             knife.polish();  
  26.             knife.package();  
  27.   
  28.             return knife;  
  29.  }  
This makes our orderknife() difficult to manage as our method is responsible for both creating the knife object and performing functions to prepare the knife. So we will try to understand the next concept - Factory Object, which is responsible for providing Knife class object just like in the real world where the Knife Factory is responsible for providing different types of knives to shopkeepers/clients.
 
Q. What is Factory Object?
 
A. The role of Factory Object is to create product objects of a particular type.
 
In general, a Factory Object is an instance of such a class, which has a method to create product objects. So in our case we will use this Factory Object class to provide us with different types of knife class objects.
 
Q. How do we implement Factory Object?
 
Step 1 - Implementing Factory Class
 
Here we are creating Knifefactory class which is responsible for creating knife object of knifetype.
  1. public class KnifeFactory  
  2. {  
  3.        public Knife createKnife(string knifetype)  
  4.        {  
  5.                 Knife knife = null;  
  6.   
  7.                 //creating knife object  
  8.                 if (knifetype == "steak")  
  9.                 {  
  10.                     knife = new SteakKnife();  
  11.                 }  
  12.                 else if (knifetype == "chefs")  
  13.                 {  
  14.                     knife = new ChefsKnife();  
  15.                 }  
  16.   
  17.                 return knife;  
  18.         }  
  19. }  
Step 2 - Implementing Store class
 
Here we will create KnifeStore class which is responsible for instantiating KnifeFactory object through constructor and then uses the same factory object to create knifetype object by calling createKnife() of factory class, inside orderKnife()  is responsible for executing common knife functions to prepare the knife irrespective of knifetype.
  1. public class KnifeStore  
  2.  {  
  3.             private KnifeFactory factory;  
  4.   
  5.             //KnifeFactory object should be passed to this constructor  
  6.             public KnifeStore(KnifeFactory factory)  
  7.             {  
  8.                 this.factory = factory;  
  9.             }  
  10.   
  11.             public Knife orderKnife(string knifetype)  
  12.             {  
  13.                 Knife knife;  
  14.   
  15.                 //using the create method in the factory  
  16.                 knife = factory.createKnife(knifetype);  
  17.   
  18.                 //prepare the knife  
  19.                 knife.sharpen();  
  20.                 knife.polish();  
  21.                 knife.package();  
  22.   
  23.                 return knife;  
  24.             }  
  25.   }  
Here we have separated the responsibilty of creating Knife Object and preparing knife to separate classes.
 
Q. Advantages of Factory Pattern?
  • The Knifestore and its orderKnife() may not be the only client of KnifeFactory. In other words,  we may need to implement bulkorder or equitytesting etc classes that can also use the same Knifefactory object .
  • Since all types of actual knife creation happen in the knifeFactory, we can simply add new knife types to our knifefactory without modifying the client code.
  • If there are multiple clients that want to instantiate the same set of classes, then by using a factory object,  we have reduced the redundant code and made the software/program easier to modify.


Similar Articles