Design Patterns Simplified - Part 4 (Abstract Factory)

I am here to continue the discussion around Design Patterns. Today we will discuss another variant of Factory design pattern called Abstract Factory.

In case, you have not had a look at our previous article about Factory pattern, go through the following link:

Before talking about its implementation let’s try to understand the purpose of the abstract factory pattern as follows.

Abstract factory pattern is next level to Simple Factory pattern where we define related factories or families of classes.

To understand this properly, let’s take the same example we took when going through Simple Factory pattern.

In Simple Factory pattern, we managed all the car brands with one interface. Now let’s assume consumer or client of the car wants next level of categorization by picking any car brand. Then how will you manage?

Here comes the Abstract Factory. It creates family of classes or related factories to address the need.

Enough theory. Now let’s talk about implementation.

How to use Abstract Factory Pattern?

Let’s try to understand using simple example.

Suppose client wants to know the car details of different kinds of brands. Car detail here is about knowing economy and premium models for any brand. For that we need to define the abstract product interface as in the following.

  1. interface IEconomy  
  2. {  
  3.     string ShowEconomy();  
  4. }  
  5. interface IPremium  
  6. {  
  7.     string ShowPremium();  
  8. }  
Now since we need to show the car details by brand, we need to create concrete product classes using the interface defined above.
  1. class Alto: IEconomy  
  2. {  
  3.     public string ShowEconomy()  
  4.     {  
  5.         return "Alto";  
  6.     }  
  7. }  
  8. class SCross: IPremium  
  9. {  
  10.     public string ShowPremium()  
  11.     {  
  12.         return "S-Cross";  
  13.     }  
  14. }  
  15. class Eon: IEconomy  
  16. {  
  17.     public string ShowEconomy()  
  18.     {  
  19.         return "Eon";  
  20.     }  
  21. }  
  22. class Elantra: IPremium  
  23. {  
  24.     public string ShowPremium()  
  25.     {  
  26.         return "Elantra";  
  27.     }  
  28. }  
Now we need to define an abstract factory interface, which can accommodate the abstract product interfaces created to define car details as in the following:
  1. interface ICarFactory  
  2. {  
  3.    IEconomy GetEconomy();  
  4.    IPremium GetPremium();  
  5. }  
Now the time has come to create the concrete family of classes to support different brands, of course by implementing the ICarFactory.
  1. class MarutiFactory: ICarFactory  
  2. {  
  3.     public IEconomy GetEconomy()  
  4.     {  
  5.         return new Alto();  
  6.     }  
  7.     public IPremium GetPremium()  
  8.     {  
  9.         return new SCross();  
  10.     }  
  11. }  
  12. class HyundaiFactory: ICarFactory  
  13. {  
  14.     public IEconomy GetEconomy()  
  15.     {  
  16.         return new Eon();  
  17.     }  
  18.     public IPremium GetPremium()  
  19.     {  
  20.         return new Elantra();  
  21.     }  

And now we have reached a point where we can use the setup created so far. Let’s do it as in the following:
  1. Console.Title = "Abstract Factory pattern demo";  
  2. ICarFactory carFactory = null;
  3. IEconomy economy = null;
  4. IPremium premium = null;
  5. //Maruti  
  6. carFactory = new MarutiFactory();
  7. economy = carFactory.GetEconomy();
  8. premium = carFactory.GetPremium();
  9. Console.WriteLine("Normal car is: " + economy.ShowEconomy() + "\nPremium Car is: " + premium.ShowPremium()); 
Output:
run
  1. //Hyundai  
  2. carFactory = new HyundaiFactory();
  3. economy = carFactory.GetEconomy();
  4. premium = carFactory.GetPremium();
  5. Console.WriteLine("Normal car is: " + economy.ShowEconomy() + "\nPremium Car is: " + premium.ShowPremium()); 
Output:
Output
 
And here goes the class diagram.
 
 
 
As you can see in the above code that client is getting the required car factory object by just creating the instance of respective car factory brand. And then it gets the required interface object by calling it's respective car factory method in order to further call the product interface methods i.e. ShowEconomy and ShowPremium.

Hope you have liked the article. Look forward for your comments/suggestions.