Abstract Factory Design Pattern

Abstract Factory patterns acts a super-factory which creates other factories. This pattern is also called as Factory of factories. In Abstract Factory pattern an interface is responsible for creating a set of related objects, or dependent objects without specifying their concrete classes.

The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes."

UML Driagram

Figure 1: UML Class Diagram for Abstract Design Pattern

Interpretation
Class/Interface Desription
Abstract Factory An interface for creating Concrete Factory. This is super factory
Concrete Factory Implements Abstract Factory interface to create the factory.
Abstract Product An interface for creating type of product.
Concrete Product Implements Abstract Product interface to create the product.
Client This is class that uses/consume the abstract factory

Sample Implementation
Let's create an application that implements abstract factory pattern: An application that inquires a car factory from a dealer and the car or automobile factory will return 2 types of car through the dealer:
  1. Economy Car
  2. Luxury Car
Download Source Code


The Project Structure


Figure 2: The project structure of Car/Auto Abstract Design Pattern

The UML Class Diagram


Figure 3: The Car Factory Class Diagram

Mapping of Car Factory Interface and Classes to Abstract Design Pattern
Class/Interface Car/Automobile Factory
Abstract Factory IFactory
Concrete Factory ToyotaFactory and FordFactory
Abstract Product IAutomobile
Concrete Product Toyota(CorollaAxioEconomy, ToyotaAvalonLuxury) and Ford(Ford300Economy, FordCougarLuxury)
Client Program, XCarDealer

Open/Closed Principle (OCP)
In OOP SOLID design, we should always maintain the OCP principle. The xCarDealer class is responsible for maintaining this (in Builder Design Pattern it acts as the Director). Just inject the Factory and it will give you the results.

The Codes

The Factories
IFactory.cs
using AbstractFactoryPattern.Auto;
namespace AbstractFactoryPattern.Factory
{
public interface IFactory
{
string Manufacturer { get; }
IAutomobile CreateEconomyCar();
IAutomobile CreateLuxuryCar();
}
}
ToyotaFactory.cs
using AbstractFactoryPattern.Factory.Toyota;
using AbstractFactoryPattern.Auto.Toyota;
namespace AbstractFactoryPattern.Factory
{
public class ToyotaFactory : IFactory
{
public string Manufacturer
{
get
{
return "Toyota";
}
}
public Auto.IAutomobile CreateEconomyCar()
{
return new CorollaAxioEconomy();
}
public Auto.IAutomobile CreateLuxuryCar()
{
return new ToyotaAvalonLuxury();
}
}
}
FordFactory.cs
using AbstractFactoryPattern.Auto.Ford;
namespace AbstractFactoryPattern.Factory
{
class FordFactory : IFactory
{
public string Manufacturer
{
get
{
return "Ford";
}
}
public Auto.IAutomobile CreateEconomyCar()
{
return new Ford300Economy();
}
public Auto.IAutomobile CreateLuxuryCar()
{
return new FordCougarLuxury();
}
}
}

The Products
IAutomobile.cs
namespace AbstractFactoryPattern.Auto
{
public interface IAutomobile
{
string Name();
string Features();
}
}
CorollaAxioEconomy.cs
using AbstractFactoryPattern.Auto;
namespace AbstractFactoryPattern.Factory.Toyota
{
public class CorollaAxioEconomy : IAutomobile
{
public string Name()
{
return "Toyota Corolla Axio";
}
public string Features()
{
return "Small Type: For Personal Use.";
}
}
}
ToyotaAvalonLuxury.cs
namespace AbstractFactoryPattern.Auto.Toyota
{
public class ToyotaAvalonLuxury : IAutomobile
{
public string Name()
{
return "Toyota Avalon";
}
public string Features()
{
return "Exeptional Experience. For men with high standard.";
}
}
}
Ford300Economy.cs
namespace AbstractFactoryPattern.Auto.Ford
{
public class Ford300Economy : IAutomobile
{
public string Name()
{
return "Ford 300";
}
public string Features()
{
return "Model 1954. For your Vintage.";
}
}
}
FordCougarLuxury.cs

The Clients
namespace AbstractFactoryPattern.Auto.Ford
{
public class FordCougarLuxury : IAutomobile
{
public string Name()
{
return "Ford Cougar";
}
public string Features()
{
return "Third generation Probe. Comfort is our business.";
}
}
}
XCarDealer.cs
using AbstractFactoryPattern.Factory;
using System;
namespace AbstractFactoryPattern.Dealers
{
class XCarDealer
{
private IFactory AutoManufacturer;
public XCarDealer(IFactory _autoManufacturer)
{
AutoManufacturer = _autoManufacturer;
}
public string GetDescription()
{
string Description = "";
Description = String.Concat(Description, "Manufacturer:", AutoManufacturer.Manufacturer, "\n");
Description = String.Concat(Description, "============================================", "\n");
Description = String.Concat(Description, " Economy", "\n");
Description = String.Concat(Description, " ", "Name : ",
AutoManufacturer.CreateEconomyCar().Name(), "\n");
Description = String.Concat(Description, " ", "Description : ",
AutoManufacturer.CreateEconomyCar().Features(), "\n");
Description = String.Concat(Description, " Luxury", "\n");
Description = String.Concat(Description, " ", "Name : ",
AutoManufacturer.CreateLuxuryCar().Name(), "\n");
Description = String.Concat(Description, " ", "Description : ",
AutoManufacturer.CreateLuxuryCar().Features(), "\n");
return Description;
}
}
}
Program.cs
using AbstractFactoryPattern.Dealers;
using AbstractFactoryPattern.Factory;
using System;
namespace AbstractFactoryPattern
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new XCarDealer(new ToyotaFactory()).GetDescription());
Console.WriteLine(new XCarDealer(new FordFactory()).GetDescription());
}
}
}

The Output

Conclusion
Abstract Factory Design Pattern is usually used in Game Production Industry because of its powerful inheritance capability.

Well! I hope I was able to reduce the complexities in explaining this Design Pattern. Thank you for your time. Your comments are valuable to me.