Abstract Factory Design Pattern
Contents
Definition
An interface for creating families of related or dependent objects without specifying their concrete classes. We can say it is just an object maker which can create more than one type of object.
The object it produces is known to the client only by that object's interface, not by the object's actual concrete implementation.
When to use it?
We use it when we have a requirement to create a set of related objects, or dependent objects which must be used together as families of objects. Concrete classes should be decoupled from clients.
How does it differ from Factory Method?
First of all, both of them fall under Creational category and it means both will solve the problem relating to object creation. Factory Method and Abstract Factory design pattern are about creating objects.
Factory Method Design Pattern
Here, we define an interface which will expose a method which will create objects for us. Return type of that method is never a concrete type; rather, it will be some interface (or may be an abstract class).
- Creates object through inheritance
- Produce only one product
- Implements code in the abstract creator that makes use of the concrete type that sub class produces
Abstract Factory Design Pattern
Here, we define an interface which will create families of related or dependent objects. In simple words, interface will expose multiple methods each of which will create some object. Again, here method return types will be generic interfaces. All these objects will together become part of some important functionality.
- Creates object through composition
- Produce families of products
- Concrete factories implements factory method to create product
UML
The classes and objects participating in the above UML class diagram are as follow.
- AbstractFactory
This is an interface for operations which is used to create abstract product.
- ConcreteFactory
This is a class which implements the AbstractFactory interface operations to create concrete products.
- AbstractProduct
This declares an interface for a type of product object
- Product
This defines a product object to be created by the corresponding concrete factory also implements the AbstractProduct interface
- Client
This is a class which uses AbstractFactory and AbstractProduct interfaces to create a family of related objects.
Real world example.
The example here has an implementation of an Abstract Factory as an Interface IMobilePhone that has methods that can create a Smart Phone object and a Normal Phone object. The client codes against IMobilePhone and gets ISmartPhone and INormalPhone interfaces.
In case of "Nokia", it creates a family of Nokia objects (SmartPhone and NormalPhone) and in case of "Samsung", creates a family of Samsung objects (SmartPhone and NormalPhone).
The client doesn't care which object (Nokia SmartPhone and NormalPhone or Samsung SmartPhone and NormalPhone), IMobilePhone interface returns as it codes against ISmartPhone and INormalPhone interface.
Who is what?
The classes and objects participating in the above class diagram can be identified as shown below.
- AbstractFactory- IMobilePhone
- ConcreteFactory - Nokia, Samsung
- AbstractProduct- ISmartPhone, INormalPhone
- Product- NokiaPixel, Nokia1600, SamsungGalaxy, SamsungGuru
- Client- MobileClient
Here are the code blocks for each participant
AbstractFactory
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'AbstractFactory' interface.
/// </summary>
interface IMobilePhone
{
ISmartPhone GetSmartPhone();
INormalPhone GetNormalPhone();
}
}
ConcreteFactory
Nokia
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'ConcreteFactory1' class.
/// </summary>
class Nokia : IMobilePhone
{
public ISmartPhone GetSmartPhone()
{
return new NokiaPixel();
}
public INormalPhone GetNormalPhone()
{
return new Nokia1600();
}
}
}
Samsung
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'ConcreteFactory2' class.
/// </summary>
class Samsung : IMobilePhone
{
public ISmartPhone GetSmartPhone()
{
return new SamsungGalaxy();
}
public INormalPhone GetNormalPhone()
{
return new SamsungGuru();
}
}
}
AbstractProduct
ISmartPhone
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'AbstractProductA' interface
/// </summary>
interface ISmartPhone
{
string GetModelDetails();
}
}
INormalPhone
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'AbstractProductB' interface
/// </summary>
interface INormalPhone
{
string GetModelDetails();
}
}
Product
NokiaPixel
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'ProductA1' class
/// </summary>
class NokiaPixel : ISmartPhone
{
public string GetModelDetails()
{
return "Model: Nokia Pixel\nRAM: 3GB\nCamera: 8MP\n";
}
}
}
SamsungGalaxy
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'ProductA2' class
/// </summary>
class SamsungGalaxy : ISmartPhone
{
public string GetModelDetails()
{
return "Model: Samsung Galaxy\nRAM: 2GB\nCamera: 13MP\n";
}
}
}
Nokia1600
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'ProductB1' class
/// </summary>
class Nokia1600 : INormalPhone
{
public string GetModelDetails()
{
return "Model: Nokia 1600\nRAM: NA\nCamera: NA\n";
}
}
}
SamsungGuru
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'ProductB2' class
/// </summary>
class SamsungGuru : INormalPhone
{
public string GetModelDetails()
{
return "Model: Samsung Guru\nRAM: NA\nCamera: NA\n";
}
}
}
Client
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// The 'Client' class
/// </summary>
class MobileClient
{
ISmartPhone smartPhone;
INormalPhone normalPhone;
public Client(IMobilePhone factory)
{
smartPhone = factory.GetSmartPhone();
normalPhone = factory.GetNormalPhone();
}
public string GetSmartPhoneModelDetails()
{
return smartPhone.GetModelDetails();
}
public string GetNormalPhoneModelDetails()
{
return normalPhone.GetModelDetails();
}
}
}
Factory Pattern Client Demo
using System;
namespace AbstractFactoryDesignPatternInCSharp
{
/// <summary>
/// Abstract Factory Pattern Demo
/// </summary>
class Program
{
static void Main()
{
IMobilePhone nokiaMobilePhone = new Nokia();
MobileClient nokiaClient = new MobileClient(nokiaMobilePhone);
Console.WriteLine("********* NOKIA **********");
Console.WriteLine(nokiaClient.GetSmartPhoneModelDetails());
Console.WriteLine(nokiaClient.GetNormalPhoneModelDetails());
IMobilePhone samsungMobilePhone = new Samsung();
MobileClient samsungClient = new MobileClient(samsungMobilePhone);
Console.WriteLine("******* SAMSUNG **********");
Console.WriteLine(samsungClient.GetSmartPhoneModelDetails());
Console.WriteLine(samsungClient.GetNormalPhoneModelDetails());
Console.ReadKey();
}
}
}
Output
See Also https://www.c-sharpcorner.com/article/abstract-factory-design-pattern-in-c-sharp/

