Here, we will see how to create Abstract Factory Design Pattern with example.
The Abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. It involves multiple factories, each responsible for creating a set of related objects.
Scenario - A cross-platform UI framework without Abstract Factory.
Problems
Consider a user interface toolkit that can generate different types of UI elements (buttons, scroll bars, etc.) for different operating systems (Windows, macOS, Linux). Instead of creating UI components directly, you use a factory to create a set of components that are consistent with the specific OS.
Example
using System;
// Abstract Products
public interface IButton
{
void Paint();
}
public interface IScrollBar
{
void Render();
}
// Concrete Products for Windows
public class WindowsButton : IButton
{
public void Paint()
{
Console.WriteLine("Rendering Windows Button");
}
}
public class WindowsScrollBar : IScrollBar
{
public void Render()
{
Console.WriteLine("Rendering Windows Scroll Bar");
}
}
// Concrete Products for macOS
public class MacOSButton : IButton
{
public void Paint()
{
Console.WriteLine("Rendering macOS Button");
}
}
public class MacOSScrollBar : IScrollBar
{
public void Render()
{
Console.WriteLine("Rendering macOS Scroll Bar");
}
}
// Concrete Products for Linux
public class LinuxButton : IButton
{
public void Paint()
{
Console.WriteLine("Rendering Linux Button");
}
}
public class LinuxScrollBar : IScrollBar
{
public void Render()
{
Console.WriteLine("Rendering Linux Scroll Bar");
}
}
// Abstract Factory
public interface IUIFactory
{
IButton CreateButton();
IScrollBar CreateScrollBar();
}
// Concrete Factories
public class WindowsFactory : IUIFactory
{
public IButton CreateButton()
{
return new WindowsButton();
}
public IScrollBar CreateScrollBar()
{
return new WindowsScrollBar();
}
}
public class MacOSFactory : IUIFactory
{
public IButton CreateButton()
{
return new MacOSButton();
}
public IScrollBar CreateScrollBar()
{
return new MacOSScrollBar();
}
}
public class LinuxFactory : IUIFactory
{
public IButton CreateButton()
{
return new LinuxButton();
}
public IScrollBar CreateScrollBar()
{
return new LinuxScrollBar();
}
}
// Client
public class Client
{
private readonly IButton _button;
private readonly IScrollBar _scrollBar;
public Client(IUIFactory factory)
{
_button = factory.CreateButton();
_scrollBar = factory.CreateScrollBar();
}
public void Run()
{
_button.Paint();
_scrollBar.Render();
}
}
// Main Program
class Program
{
static void Main(string[] args)
{
IUIFactory factory = new WindowsFactory(); // Choose the factory based on the OS
Client client = new Client(factory);
client.Run();
factory = new MacOSFactory(); // Switch to macOS factory
client = new Client(factory);
client.Run();
factory = new LinuxFactory(); // Switch to Linux factory
client = new Client(factory);
client.Run();
}
}
IButton
, IScrollBar
)
define the common interface for UI components.WindowsButton
, MacOSButton
,
LinuxButton
, etc.) provide specific implementations
for each OS.IUIFactory
) declares
methods for creating abstract products.WindowsFactory
,
MacOSFactory
, LinuxFactory
) implement methods
to create concrete products.Output
Think of a car manufacturing company that produces different models of cars (sedans, SUVs) and different trims (luxury, standard). Each model and trim has its own set of components like seats, wheels, and engines.
When you choose a SedanFactory, you get a set of components that are specifically designed for a sedan. Similarly, SUVFactory provides components designed for SUVs.
Example
// Abstract Products
using System;
public interface ISeats
{
string GetSeatType();
}
public interface IWheels
{
string GetWheelType();
}
public interface IEngine
{
string GetEngineType();
}
// Concrete Products for Sedan
public class SedanSeats : ISeats
{
public string GetSeatType() => "Luxury Leather Seats for Sedan";
}
public class SedanWheels : IWheels
{
public string GetWheelType() => "Alloy Wheels for Sedan";
}
public class SedanEngine : IEngine
{
public string GetEngineType() => "V6 Engine for Sedan";
}
// Concrete Products for SUV
public class SUVSeats : ISeats
{
public string GetSeatType() => "Luxury Leather Seats for SUV";
}
public class SUVWheels : IWheels
{
public string GetWheelType() => "Off-road Wheels for SUV";
}
public class SUVEngine : IEngine
{
public string GetEngineType() => "V8 Engine for SUV";
}
// Abstract Factory
public interface ICarFactory
{
ISeats CreateSeats();
IWheels CreateWheels();
IEngine CreateEngine();
}
// Concrete Factories
public class SedanFactory : ICarFactory
{
public ISeats CreateSeats() => new SedanSeats();
public IWheels CreateWheels() => new SedanWheels();
public IEngine CreateEngine() => new SedanEngine();
}
public class SUVFactory : ICarFactory
{
public ISeats CreateSeats() => new SUVSeats();
public IWheels CreateWheels() => new SUVWheels();
public IEngine CreateEngine() => new SUVEngine();
}
// Client Code
public class CarManufacturer
{
private readonly ISeats _seats;
private readonly IWheels _wheels;
private readonly IEngine _engine;
public CarManufacturer(ICarFactory factory)
{
_seats = factory.CreateSeats();
_wheels = factory.CreateWheels();
_engine = factory.CreateEngine();
}
public void DisplayCarDetails()
{
Console.WriteLine($"Seats: {_seats.GetSeatType()}");
Console.WriteLine($"Wheels: {_wheels.GetWheelType()}");
Console.WriteLine($"Engine: {_engine.GetEngineType()}");
}
}
// Usage
class Program
{
static void Main(string[] args)
{
// Create a sedan
ICarFactory sedanFactory = new SedanFactory();
CarManufacturer sedan = new CarManufacturer(sedanFactory);
sedan.DisplayCarDetails();
Console.WriteLine();
// Create an SUV
ICarFactory suvFactory = new SUVFactory();
CarManufacturer suv = new CarManufacturer(suvFactory);
suv.DisplayCarDetails();
}
}
Output