Design Patterns - Factory

In this article, I am explaining the Factory design pattern from the Gang of Four (GoF) design patterns

Factory design pattern is one of the design patterns among the Gang of Four (GoF) design patterns. It is a creational design pattern.
 
This design pattern hides the creation of the objects and allows the objects to be created at run time when required. This design pattern would allow us to create objects without exposing the creation logic.
 
An interface is used to create the objects. But the subclass will decide which class to be initiated. The UML diagram for the factory design pattern is given below.
 
Design Patterns - Factory
 
An example program for this design pattern is given below. In this sample program, we are writing a program to give guidance for the production support issues. A production support team might handle different types of issues. These can be application issues, business issues, database issues, or installation issues, etc. Different types of issues might be handled in different ways.
 
For example, if the issue is an application issue, we might look into the source code and identify the root cause for the issue. We may contact the development team for help.
 
Similarly, if the issue is an installation issue, we might check the installation sequence and can contact the installation team to verify the installation in the client environment.
 
The following program will generate guidance to handle different types of issues using the Factory method. This is a very basic and simple example of the Factory design pattern.
 

Interface

 
First, we should create an interface as given below.
  1.    public interface IProductionIssue  
  2.     {  
  3.          void resolveIssue();  
  4.     }  
The interface IProductionIssue has an abstract method called resolveIssue().
 

Concrete Classes

 
Next, we need to create concrete classes for different issues by implementing the IProductionIssue interface as below.
 
BusinessIssue class is created to give guidance for business-related issues.
  1.    public class BusinessIssue: IProductionIssue  
  2.    {  
  3.        public void resolveIssue()  
  4.        {  
  5.            Console.WriteLine(" This is a Business Issue \n Contact the business people \n---------------------------");  
  6.        }  
  7.    
  8.    }  
DatabaseIssue class is created to give guidance for database issues.
  1.    public class DatabaseIssue :IProductionIssue  
  2.     {  
  3.         public void resolveIssue()  
  4.         {  
  5.             Console.WriteLine(" This is a database related Issue. \n Check the database \n Contact the db team if required \n---------------------------");  
  6.         }  
  7.     }  
ApplicationIssue class is created to give guidance for application-related issues.
  1. public class ApplicationIssue:IProductionIssue    
  2.    {    
  3.        public void resolveIssue()    
  4.        {    
  5.            Console.WriteLine(" This is a application Issue \n Debug the code \n Contact Dev team if required.\n---------------------------");    
  6.        }    
  7.    }    

Creator Class

 
The factory method is declared in IssueFactory class as below.
 
This is the creator class.
  1. public abstract class IssueFactory  
  2. {  
  3.     public abstract IProductionIssue getResolutionSteps(string issueType);  
  4. }  
IssueFactory is an abstract class with an abstract method called getResolutionSteps (string issueType).
 
The return type of this method is IProductionIssue
 

Concrete Creator Class

 
Then, we need to create a concrete creator class next. In the below class, we are defining the abstract method getResolutionSteps() in the IssueFactory class
 
Please refer to the code snippet below.
  1. public class FixIssue : IssueFactory  
  2. {  
  3.     public override IProductionIssue getResolutionSteps(string issueType)  
  4.     {  
  5.         
  6.         switch (issueType)  
  7.         {  
  8.             case "business":  
  9.                 return new BusinessIssue();  
  10.             case "database":  
  11.                 return new DatabaseIssue();  
  12.             case "application":  
  13.                 return new ApplicationIssue();  
  14.             default:  
  15.                 throw new ApplicationException(string.Format("Cannot find the resolution guide for {0} issue.\n Please contact the support",issueType));  
  16.         }  
  17.     }  
  18. }  
We are passing the type of the issue as a parameter to the method, getResolutionSteps().
 
And, based on the type (example - business/database/application), we will return the corresponding class instance.
 
Main Program
 
The main program can be created as below.
  1. class ClientProgram  
  2. {   
  3.     static void Main(string[] args)  
  4.     {  
  5.     Console.WriteLine("Design pattern  : Factory \n*************************");  
  6.   
  7.   
  8.     IssueFactory issuefactory = new FixIssue();  
  9.   
  10.     IProductionIssue business_issue = issuefactory.getResolutionSteps("business");  
  11.     IProductionIssue database_issue = issuefactory.getResolutionSteps("database");  
  12.     IProductionIssue application_issue = issuefactory.getResolutionSteps("application");  
  13.   
  14.     business_issue.resolveIssue();  
  15.     database_issue.resolveIssue();  
  16.     application_issue.resolveIssue();  
  17.   
  18.     Console.ReadKey();  
  19.     }  
  20. }  
Here, we are creating class instances by passing the issue type.
 
Based on the issue type, the instance will be created and assigned to the IProductionIssue variable.