Design Patterns Simplified - Part 3 (Simple Factory)

I am here to continue the discussion of Design Patterns. Today we will explain another creational design pattern called Simple Factory.

In case you have not had a look at our previous articles, go through the following link:

Before talking about its implementation let's begin with some fundamental questions as in the following.

Purpose of the Factory pattern

I can think of two main objectives of using the Factory pattern. One is to achieve loose coupling between the client and business layer, another is to keep all the code for all the object instantiation logic in one place.

Purpose of loose coupling

In modern software development where changes in existing systems are frequent and software design is expected to be scalable, not having a loosely-coupled design can create many problems.

For example, in an application with a 3-layer architecture, if object creation logic is at the client side, for any new addition of concrete classes, the developer needs to modify not just the business but the client layer as well. Think about the maintainability and added testing effort.

How about if the client is only aware of the high-level contracts and not about its concreate implementation?

Yes, you got it right! The client just must pass the type of the object it needs and it will get it using the Factory Pattern.

Enough theory. Now let's talk about implementation.

How to use the Simple Factory Pattern

Let's try to understand using a simple example.

Assume the client wants to know the on-road price of various brands of cars and have an interface as in the following.

  1. interface ICar
  2. {  
  3.     string GetOnRoadPrice(string model);  
  4. }  

We need to create a Factory class now that will sit between the client and business layers and it will provide the required object to the client based on the car brand passed.

  1. class CarFactory   
  2. {  
  3.     static public ICar GetCar(string carBrand)   
  4.     {  
  5.         if (carBrand == "Maruti")   
  6.         {  
  7.             return new Maruti();  
  8.         }   
  9.         else if (carBrand == "Hyundai")   
  10.         {  
  11.             return new Hyundai();  
  12.         }  
  13.         return null;  
  14.     }  
  15. }  

And here goes the concreate business classes.

  1. class Maruti: ICar   
  2. {  
  3.     public string GetOnRoadPrice(string model)   
  4.     {  
  5.         if (model == "Alto 800 VXI")   
  6.         {  
  7.             return "3.4 Lakhs INR";  
  8.         }   
  9.         else   
  10.         {  
  11.             return "Information not available!";  
  12.         }  
  13.     }  
  14. }  
  15. class Hyundai: ICar   
  16. {  
  17.     public string GetOnRoadPrice(string model)   
  18.     {  
  19.         if (model == "Grand i10 Magna 1.2 BSV")   
  20.         {  
  21.             return "5.4 Lakhs INR";  
  22.         }   
  23.         else   
  24.         {  
  25.             return "Information not available!";  
  26.         }  
  27.     }  
  28. }  

Now let's see how the client can use the setup we have created so far.

  1. //Client side  
  2. Console.Title = "Factory pattern demo";
  3. ICar car = null;
  4. string model = null;  
  5. //Maruti 
  6. car = CarFactory.GetCar("Maruti");  
  7. model = "Alto 800 VXI";
  8. Console.WriteLine("On-road price for {0} car is: {1} ", model, car.GetOnRoadPrice(model));  

  1. //Hyundai  
  2. car = CarFactory.GetCar("Hyundai");  
  3. model = "Grand i10 Magna 1.2 BSV";
  4. Console.WriteLine("On-road price for {0} car is: {1} ", model, car.GetOnRoadPrice(model));

And here goes the class diagram.
As you can see in the preceding code, the client is getting the required object by just passing the car brand. And then it calls the GetOnRoadPrice method to get the On-road price by passing model name. So just to summarize, using simple factory, we achieved the following.
  • Loose coupling between client and business layers.

  • Placed object creation logic at common place.

  • Abstracted concreate classes (Maruti, Hyundai) from client.

I hope you have liked this article. I look forward to your comments/suggestions.