Abstract Factory Design Pattern

Anubhav Gupta
2 min readOct 26, 2024

--

The Abstract Factory design pattern is a creational pattern that provides an interface to create families of related or dependent objects without specifying their concrete classes. It’s useful when a system needs to work with multiple families of related products but shouldn’t depend on the specific classes of these products.

Key Concepts

  1. Abstract Factory Interface: Declares a set of methods for creating abstract products.
  2. Concrete Factory: Implements the abstract factory interface, creating concrete products.
  3. Abstract Product: Declares interfaces for a set of related products.
  4. Concrete Product: Implements the abstract product interface.

Example Use Case

Consider a UI theme where you need a different look for buttons and textboxes depending on the operating system (e.g., Windows, macOS).

  • Abstract Factory: GUIFactory (interface with methods to create buttons and textboxes).
  • Concrete Factories: WindowsFactory, MacFactory (implement GUIFactory to create Windows or Mac-style buttons and textboxes).
  • Abstract Product: Button and TextBox (define interfaces for buttons and textboxes).
  • Concrete Products: WindowsButton, MacButton, WindowsTextBox, MacTextBox (implement abstract products).
// Abstract Products
interface Button {
void paint();
}

interface TextBox {
void render();
}

// Concrete Products for Windows
class WindowsButton implements Button {
public void paint() {
System.out.println("Rendering Windows Button");
}
}

class WindowsTextBox implements TextBox {
public void render() {
System.out.println("Rendering Windows TextBox");
}
}

// Concrete Products for Mac
class MacButton implements Button {
public void paint() {
System.out.println("Rendering Mac Button");
}
}

class MacTextBox implements TextBox {
public void render() {
System.out.println("Rendering Mac TextBox");
}
}

// Abstract Factory
interface GUIFactory {
Button createButton();
TextBox createTextBox();
}

// Concrete Factories
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public TextBox createTextBox() {
return new WindowsTextBox();
}
}

class MacFactory implements GUIFactory {
public Button createButton() {
return new MacButton();
}
public TextBox createTextBox() {
return new MacTextBox();
}
}

// Client
class Application {
private Button button;
private TextBox textBox;

public Application(GUIFactory factory) {
button = factory.createButton();
textBox = factory.createTextBox();
}

public void paint() {
button.paint();
textBox.render();
}
}

// Usage
public class Main {
public static void main(String[] args) {
GUIFactory factory;

// Depending on OS type or configuration
String osType = "Windows"; // This could be dynamically determined
if (osType.equals("Windows")) {
factory = new WindowsFactory();
} else {
factory = new MacFactory();
}

Application app = new Application(factory);
app.paint();
}
}

Benefits

  • Isolation of Concrete Classes: The client only interacts with abstract interfaces.
  • Easily Extendable: Adding a new family of products requires creating a new factory and products without changing existing code.
  • Consistency: Ensures related products are used together.

When to Use

  • When a system needs to be independent of how its products are created or composed.
  • When the system should work with multiple families of related products.

--

--

Anubhav Gupta
Anubhav Gupta

Written by Anubhav Gupta

Machine Learning , Computer Vision and Deep Learning Enthusiast