Introduction
In this article we will understand Abstract Factory Pattern. This article is third part of Factory Patterns article series and is the continuation of Part 1 (Simple Factory Pattern) and Part 2 (Factory Method Pattern). In first part we have learned Simple Factory Pattern and in second part we have learned Factory method Pattern, now its turn for Abstract Factory Pattern. If you haven’t gone through the first and second part, I will suggest you to do so then continue with this article.
Outlines
Part 3 - Abstract Factory Pattern
- What is Abstract Factory Pattern
- When to use Abstract Factory Pattern
- Understand Definition with Example
- Problem with Abstract Factory Pattern
What is Abstract Factory Pattern
Abstract Factory Pattern is a part of Gang of Four (GoF) book and comes in the category of Creational Pattern. Following is the definition of Abstract Factory Pattern taken from Gang of Four (GoF) book
“Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”
We will understand this definition in detail under "Understand Definition with Example" section of this article.
When to use Abstract Factory Pattern
Whenever we need to create different kind of related objects (of a group/set) then Abstract Factory Pattern is a choice. It provides different kind of Factories. Each factory will create a particular kind of related objects. That's why sometime we call Abstract Factory Pattern as Factory of Factories. Simple Factory Pattern and Factory Method Pattern provide one kind on objects only (in our examples all those objects were of type IFan).
Note: Abstract Factory Pattern can be use along with Factory Method Pattern if needed.
Now, other than Fan, if we need to create more electrical equipments like Tubelights or Switches we will go for Abstract Factory. To make it more clear, let's extend the scenario where we will need to create different kind of related objects of a group (objects under group of Electrical Equipments). We will continue with the similar example which we took in part 2 of this article series.
Now let’s understand extended scenario: There is a electrical company which makes various kind of electrical equipments namely Fan and Tubelight. Currently company is in India only and called as Indian Electrical company. Now same company wants to setup new branch in US namely US Electrical company which would be manufacturing electrical equipment called Fan and Tubelight as per US standards. So here we have two kind of group of Electrical Equipments - called as Indian Electrical Equipments and US Electrical Equipments. And related objects in these groups are Fan and Tubelight (There may be more such electrical equipments).
Understand Definition with Example
Let’s understand the definition of Abstract Factory Pattern with the help of above mentioned scenario. First create design diagram of above mentioned scenario and try to correlate the definition with this scenario. Following is the design diagram shows the required entities to implements above mentioned scenario.
In above diagram IElectricalFactory provides an interface to the client for creating families of related or dependent objects. Here we have two concrete implementation of that interface - IndianElectricalFactory and USElectricalFactory classes. These two classes are manufacturing two different type of families of related objects - Fan and TubeLight. IndianFan and IndianTubelight belong to IndianElectricalFactory family. USTubelight and USFan classes which belong to a USElectricalFactory family.
Main Component/Participants of Abstract Factory Pattern
- AbstractFactory (IElectricalFactory)
- ConcreteFactory (IndianElectricalFactory, USElectricalFactory)
- AbstractProduct (IFan, ITubeLight)
- ConcreteProduct (IndianFan, IndianTubelight, USFan, USTubelight)
Following is step by step implementation of above mentioned scenario:
Create two interface called IFan and ITubelight.
interface IFan
{
void SwithOn();
}
interface ITubelight { }
Create Two concreate classes as given below by implementing IFan and ITubelight. Implementation of interfaces will be according to Indian electrical equipment standard.
class IndianFan : IFan { }
class IndianTubelight : ITubelight { }
Create an IElectricalFactory interface, this interface is actual Abstract Factory which will create families of related objects.
interface IElectricalFactory
{
IFan GetFan();
ITubelight GetTubeLight();
}
Create an IndianElecticalFactory class and inherit it from IElectricalFactory interface. It will implementation of two methods called GetFan and will GetTubeLight. GetFan returns object of IndianFan class as IFan interface is implemented by IndianFan class. Similarly GetTubeLight will return the object of IndianTubelight class.
class IndianElectricalFactory : IElectricalFactory
{
public IFan GetFan()
{
return new IndianFan();
}
public ITubelight GetTubeLight()
{
return new IndianTubelight();
}
}
So far IndianElecticalFactory class is ready to create IndianFan and IndianTubelight. Now let’s see how client can create them.
static void Main(string[] args)
{
IElectricalFactory electricalFactory = new IndianElectricalFactory();
IFan fan = electricalFactory.GetFan();
fan.SwithOn();
Console.ReadKey();
}
As we discussed above section, company wants to setup new electrical company in US and company name will be USElectricalFactory. In the same application we will add two new classes called USFan and USTubelight by implementing required interfaces. Here implementation of IFan and ITubeLight interfaces will be according to US electrical equipment standard.
class USFan : IFan { }
class USTubelight : ITubelight { }
Finally create USElectricalFactory class which is also inherited from IElectricalFactory.
class USElectricalFactory : IElectricalFactory
{
public IFan GetFan()
{
return new USFan();
}
public ITubelight GetTubeLight()
{
return new USTubelight();
}
}
Now if client wants to get USElectrical equipment then this can be done just by doing one change in client code, as shown below:
IElectricalFactory electricalFactory = new USElectricalFactory();
Problem with Abstract Factory Pattern
Only problem may come if we change the interface provided by Abstract Factory itself. Thats rare and every programs which follows the design philosophy of "Program to an interface, not an implementation" suffers with this problem. Same problem is discussed at this stackoverflow page. In our case, if any change occurs in IElectricalFactory interface all factories need to change.
Conclusion
In this article, we had a walkthrough to learn Abstract Factory Pattern and its use. We understood the context of Abstract Factory Pattern and how to use it to enhance maintainability of application. Thanks for reading. Your comments and suggestions for improvement are most welcome.
References