Factory Method Design Pattern in C# with Example

1. Definition

The Factory Method pattern is a creational design pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created.

2. Problem Statement

Imagine you're building a UI library and you want to ensure that each UI element, such as buttons, checkboxes, etc., can be drawn consistently but also be customizable for different operating systems. If you hard-code the object creation, it might be challenging to extend and modify the UI elements for different platforms.

3. Solution

The Factory Method pattern solves this problem by defining a method for creating objects, which is then overridden by derived classes to produce the specific objects. This allows for flexibility in the type and nature of objects that can be created.

4. Real-World Use Cases

1. GUI libraries where each operating system provides a different implementation of a button, scrollbar, or window.

2. E-commerce platforms that need to provide different payment method options.

3. Middleware or plugins where specific implementations are swapped out based on configurations.

5. Implementation Steps

1. Create an interface or abstract class that declares a factory method.

2. Concrete classes implement this factory method to instantiate and return products.

3. The client code uses the factory method rather than creating instances of the product directly.

6. Implementation in C#

// Abstract product
public interface IButton
{
    void Render();
}

// Concrete products
public class WindowsButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Rendering a Windows button.");
    }
}

public class MacOSButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Rendering a MacOS button.");
    }
}

// Creator abstract class
public abstract class UIFactory
{
    public abstract IButton CreateButton();
}

// Concrete creators
public class WindowsUIFactory : UIFactory
{
    public override IButton CreateButton()
    {
        return new WindowsButton();
    }
}

public class MacOSUIFactory : UIFactory
{
    public override IButton CreateButton()
    {
        return new MacOSButton();
    }
}

public class Program
{
    public static void Main()
    {
        UIFactory factory;

        if (Environment.OSVersion.Platform == PlatformID.Win32NT)
        {
            factory = new WindowsUIFactory();
        }
        else
        {
            factory = new MacOSUIFactory();
        }

        var button = factory.CreateButton();
        button.Render();
    }
}

Output:

Rendering a Windows button.
// The output will vary based on the OS you're running. The above output is for a Windows environment.

Explanation:

In this example, IButton represents the abstract product. 

WindowsButton and MacOSButton are concrete products. 

The UIFactory is the abstract creator, which declares the factory method CreateButton()

Concrete creators (WindowsUIFactory and MacOSUIFactory) implement this method to instantiate specific buttons. 

The Program class, which is our client, utilizes the factory to create and render a button based on the current operating system.

7. When to use?

Use the Factory Method pattern when:

1. A class can't anticipate the type of objects it needs to create beforehand.

2. A class wants its subclasses to specify the objects it creates.

3. You want to localize the knowledge of which class gets instantiated to its subclasses.


Comments