The Abstract Factory Design Pattern

Erik Zhou | Apr 17, 2023 min read

The abstract factory pattern is a creational design pattern that helps create related objects without specifying their exact classes. This is useful when you need to create groups of objects that are interdependent. In this blog post, we will discuss the abstract factory pattern, and how to use it.

What is the Abstract Factory Design Pattern?

The abstract factory pattern helps create related objects using a shared interface, without specifying the exact class of each object. It’s useful when dealing with complicated object creation that involves many related classes.

The abstract factory pattern simplifies creating objects by letting separate factory classes handle the process.

Implementing the Abstract Factory Design Pattern

Now we can take a look at how to implement the abstract factory pattern. Let’s say we needed to be able to render different UI components with different themes. We would want to have a factory generate each component based on a specific theme.

Step 1: Define common interfaces

First, we need to define common interfaces for the UI components and the abstract factory.

public interface IButton
{
    void Render();
}

public interface ITextInput
{
    void Render();
}

public interface IGuiFactory
{
    IButton CreateButton();
    ITextInput CreateTextInput();
}

Step 2: Create concrete UI component classes

Next, we’ll create concrete UI component classes that implement the common interfaces for each theme.

public class LightButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Rendering light theme button");
    }
}

public class LightTextInput : ITextInput
{
    public void Render()
    {
        Console.WriteLine("Rendering light theme text input");
    }
}

public class DarkButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Rendering dark theme button");
    }
}

public class DarkTextInput : ITextInput
{
    public void Render()
    {
        Console.WriteLine("Rendering dark theme text input");
    }
}

Step 3: Create concrete factory classes

Now, we’ll create concrete factory classes that implement the IGuiFactory interface to create UI components for each theme.

public class LightThemeFactory : IGuiFactory
{
    public IButton CreateButton()
    {
        return new LightButton();
    }

    public ITextInput CreateTextInput()
    {
        return new LightTextInput();
    }
}

public class DarkThemeFactory : IGuiFactory
{
    public IButton CreateButton()
    {
        return new DarkButton();
    }

    public ITextInput CreateTextInput()
    {
        return new DarkTextInput();
    }
}

Step 4: Use the abstract factory to create objects

Finally, we can use the abstract factory to create UI component objects based on the selected theme.

public class Application
{
    private IButton _button;
    private ITextInput _textinput;

    public Application(IGuiFactory factory)
    {
        _button = factory.CreateButton();
        _textinput = factory.CreateTextInput();
    }

    public void Render()
    {
        _button.Render();
        _textinput.Render();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IGuiFactory factory;

        if (args.Length > 0 && args[0] == "dark")
        {
            factory = new DarkThemeFactory();
        }
        else
        {
            factory = new LightThemeFactory();
        }

        var app = new Application(factory);
        app.Render();
    }
}

In this example, we’ve shown how to implement the abstract factory design pattern in C# by creating a GUI application with multiple themes. By using the abstract factory pattern, we can easily create new UI components and maintain consistency within the application, without directly instantiating their classes.