Abstract Factory Design Pattern

Introduction:

Sometimes you want to create an instance of class that is related to a family of classes without specifying the exact concert class. Factory design pattern came to solve this issue and make it easy for us.

In order to avoid duplicating the code that make the decision everywhere an instance is created, we need a mechanism for creating instances of related classes without necessarily knowing which will be instantiated.

There are 2 types of Factory Design Pattern:

  1. Simple Factory: the result of the Factory method is a subclass (inherited class) of the Abstract Class. The choice of which subclass to instantiate is completely defined by which method is used, and is unknown to the client.
  2. Abstract Factory: an abstract class defining a common protocol of Factory methods. Concrete subclasses of the abstract factory implement this protocol to answer instances of the appropriate suite of classes.

Example:

Suppose we have 2 Audio/Video devices (CD & DVD ). Both devices has audio and video features but those devices does not have the same shared parent class. And we need to simplify the creational of objects. The best solution for this is to go with abstract factory design pattern. Below is the diagram illustrating how we can design classes to serve the main purpose.

Interfaces:

  • IVideoDevice: is the interface that all Video classes inherits.
  • IAudioDevice: is the interface that all Audio classes inherits.
  • IAudioVideoDevice: is the interface that all Audio/Video classes inherits.

Classes:

  • CDAudio: Inherits from IAudioDevice and implement the needed methods.
  • CDVideo: Inherits from IVideoDevice and implement the needed methods.
  • CDDevice: Inherits from IAudioVideoDevice and create the correct Audio/Video devices.
  • DVDAuio: Inherits from IAudioDevice and implement the needed methods.
  • DVDVideo: Inherits from IVideoDevice and implement the needed methods.
  • DVDDevice: Inherits from IAudioVideoDevice and create the correct Audio/Video devices.
  • AbstractFactory: Is responsible of creating the correct Audio/Video objects according to a string parameter passed to it( this might be changed to enum or something like that)

FactoryDesignPattern

static void Main(string[] args)
{
string deviceName;
deviceName = Console.ReadLine();
IAudioVideoDevice device = AbstractFactory.Create(deviceName);
Console.WriteLine(device.GetAudioDevice().GetAudioDeviceName());
Console.WriteLine(device.GetVideoDevice().GetVideoDeviceName());
Console.ReadKey();
}
class AbstractFactory
{
public static IAudioVideoDevice Create( string deviceName)
{
switch (deviceName.ToLower())
{
case “CD”:
return new  CDDevice();
case “dvd”:
return new DVDDevice();
default:
return new CDDevice();
}
}
}
class DVDDevice:IAudioVideoDevice
{
#region IAudioVideoDevice Members
public IAudioDevice GetAudioDevice()
{
return new DVDAudio();
}
public IVideoDevice GetVideoDevice()
{
return new DVDVideo();
}
#endregion
}
class CDDevice:IAudioVideoDevice
{
#region IAudioVideoDevice Members
public IAudioDevice GetAudioDevice()
{
return new CDAudio();
}
public IVideoDevice GetVideoDevice()
{
return new CDVideo();
}
#endregion
}
class CDAudio:IAudioDevice
{
#region IAudioDevice Members
public string GetAudioDeviceName()
{
return “CD Audio”;
}
#endregion
}
class CDVideo:IVideoDevice
{
#region IVideoDevice Members
public string GetVideoDeviceName()
{
return “CD Video”;
}
#endregion
}
class DVDAudio:IAudioDevice
{
#region IAudioDevice Members
public string GetAudioDeviceName()
{
return “DVD Audio”;
}
#endregion
}
class DVDVideo:IVideoDevice
{
#region IVideoDevice Members
public string GetVideoDeviceName()
{
return “DVD Video”;
}
#endregion
}
interface IAudioVideoDevice
{
IAudioDevice GetAudioDevice();
IVideoDevice GetVideoDevice();
}
interface IAudioDevice
{
string GetAudioDeviceName();
}
interface IVideoDevice
{
string GetVideoDeviceName();
}

Download Code