Abstract Factory Pattern in C#: What It Is and How It Works
Abstract Factory Pattern in C# is a design pattern that provides an interface to create families of related objects without specifying their concrete classes. It helps you produce different sets of objects that belong together, making your code flexible and easy to extend.How It Works
Imagine you want to build different types of furniture sets, like a modern set and a classic set. Each set has matching chairs and sofas. The Abstract Factory Pattern acts like a factory manager who knows how to create the right chair and sofa for each style without you needing to know the details.
In C#, this pattern uses interfaces or abstract classes to define methods for creating related objects. Concrete factories implement these methods to produce specific object variants. Your code calls the factory interface, and the right objects are created behind the scenes, keeping your code clean and easy to change.
Example
This example shows how to create two furniture styles: Modern and Victorian. Each style has its own chair and sofa. The abstract factory interface defines methods to create these, and concrete factories implement them. The client uses the factory to get matching furniture without knowing the details.
using System; // Abstract product interfaces interface IChair { void SitOn(); } interface ISofa { void LieOn(); } // Concrete products for Modern style class ModernChair : IChair { public void SitOn() => Console.WriteLine("Sitting on a modern chair."); } class ModernSofa : ISofa { public void LieOn() => Console.WriteLine("Lying on a modern sofa."); } // Concrete products for Victorian style class VictorianChair : IChair { public void SitOn() => Console.WriteLine("Sitting on a Victorian chair."); } class VictorianSofa : ISofa { public void LieOn() => Console.WriteLine("Lying on a Victorian sofa."); } // Abstract factory interface interface IFurnitureFactory { IChair CreateChair(); ISofa CreateSofa(); } // Concrete factories class ModernFurnitureFactory : IFurnitureFactory { public IChair CreateChair() => new ModernChair(); public ISofa CreateSofa() => new ModernSofa(); } class VictorianFurnitureFactory : IFurnitureFactory { public IChair CreateChair() => new VictorianChair(); public ISofa CreateSofa() => new VictorianSofa(); } // Client code class Client { private IChair _chair; private ISofa _sofa; public Client(IFurnitureFactory factory) { _chair = factory.CreateChair(); _sofa = factory.CreateSofa(); } public void UseFurniture() { _chair.SitOn(); _sofa.LieOn(); } } class Program { static void Main() { IFurnitureFactory modernFactory = new ModernFurnitureFactory(); Client modernClient = new Client(modernFactory); modernClient.UseFurniture(); IFurnitureFactory victorianFactory = new VictorianFurnitureFactory(); Client victorianClient = new Client(victorianFactory); victorianClient.UseFurniture(); } }
When to Use
Use the Abstract Factory Pattern when your code needs to create families of related objects that must work together, and you want to keep your code independent from how these objects are made. It is helpful when you want to switch between different product sets easily without changing client code.
For example, in a game, you might have different themes like medieval or futuristic. Each theme has its own set of characters, weapons, and environments. Using this pattern lets you swap themes by changing the factory, keeping your game flexible and organized.
Key Points
- The Abstract Factory Pattern creates families of related objects without specifying their concrete classes.
- It uses interfaces or abstract classes for factories and products.
- It helps keep client code independent from specific object creation.
- It is useful for supporting multiple product variants or themes.
- It improves code flexibility and makes adding new product families easier.