How to use Abstract Factory Pattern in C#

This post shows you how to use Abstract Factory pattern in C# code.

Abstract Factory pattern is like a super factory, to create other factories (create objects). This super factory is also called a factory of factories. This type of design pattern is a type of creational pattern, and is one of the best and most effective ways to create objects.

In Abstract Factory pattern, an interface is responsible for creating a factory for similar objects without specifying their class. Each factory can produce objects of different factory types (Factory Pattern).

Regular usage: Very high

UML Diagram

Abstract Factory Pattern in C#

Classes and objects that participate in this pattern include:

  • AbstractFactory: declare an interface for functions to create abstract products.
  • ConcreteFactory: deploy functions from interfaces to create specific product objects.
  • AbstractProduct: declares an interface for product type.
  • Product: gives the product objects created by ConcreteFactory, deploy Abstract Product interface.
  • Client: uses interfaces declared by AbstarctFactory and AbstractProduct classes.

Implement c# code

class AbstractFactoryPattern
{
    public static void Main()
    {
        // Abstract factory #1
        AbstractFactory factory1 = new ConcreteFactory1();
        Client client1 = new Client(factory1);
        client1.Run();
        // Abstract factory #2
        AbstractFactory factory2 = new ConcreteFactory2();
        Client client2 = new Client(factory2);
        client2.Run();
    }
}

abstract class AbstractFactory
{
    public abstract AbstractProductA CreateProductA();
    public abstract AbstractProductB CreateProductB();
}

class ConcreteFactory1 : AbstractFactory
{
    public override AbstractProductA CreateProductA()
    {
        return new ProductA1();
    }
    public override AbstractProductB CreateProductB()
    {
        return new ProductB1();
    }
}

class ConcreteFactory2 : AbstractFactory
{
    public override AbstractProductA CreateProductA()
    {
        return new ProductA2();
    }
    public override AbstractProductB CreateProductB()
    {
        return new ProductB2();
    }
}

abstract class AbstractProductA
{
}

abstract class AbstractProductB
{
    public abstract void Interact(AbstractProductA a);
}

class ProductA1 : AbstractProductA
{
}

class ProductB1 : AbstractProductB
{
    public override void Interact(AbstractProductA a)
    {
        Console.WriteLine(this.GetType().Name +
          " interacts with " + a.GetType().Name);
    }
}

class ProductA2 : AbstractProductA
{
}

class ProductB2 : AbstractProductB
{
    public override void Interact(AbstractProductA a)
    {
        Console.WriteLine(this.GetType().Name +
          " interacts with " + a.GetType().Name);
    }
}

class Client
{
    private AbstractProductA _abstractProductA;
    private AbstractProductB _abstractProductB;

    // Constructor

    public Client(AbstractFactory factory)
    {
        _abstractProductB = factory.CreateProductB();
        _abstractProductA = factory.CreateProductA();
    }

    public void Run()
    {
        _abstractProductB.Interact(_abstractProductA);
    }
}

Result:

ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2