Abstract Factory Design Pattern in Java
Learn Abstract Factory Design Pattern in Java with diagrams, real-world examples, framework usage, code examples, benefits, limitations, and interview questions.
Introduction
In the previous article, we learned Factory Method Pattern.
Factory Method creates one object at a time.
But what if we need to create an entire family of related objects together?
Examples:
- Windows UI Components
- Mac UI Components
- AWS Cloud Resources
- Azure Cloud Resources
- Insurance Product Families
- Banking Product Families
This is where the Abstract Factory Pattern comes into play.
Purpose of Abstract Factory Pattern
The main purpose of Abstract Factory is:
Create families of related objects without specifying their concrete classes.
Instead of creating a single object:
Factory Method
↓
Creates One Product
Abstract Factory:
Abstract Factory
↓
Creates Multiple Related Products
Real World Analogy
Imagine you buy a complete furniture set.
Modern Set:
- Modern Chair
- Modern Table
- Modern Sofa
Classic Set:
- Classic Chair
- Classic Table
- Classic Sofa
You don't buy individual pieces randomly.
You choose an entire family.
This is exactly what Abstract Factory does.
Problem Without Abstract Factory
Suppose we are building a UI application.
We need:
Button
Textbox
Checkbox
For:
Windows
Mac
Linux
Without Abstract Factory:
Button button = new WindowsButton();
Textbox textbox = new MacTextbox();
Checkbox checkbox = new LinuxCheckbox();
This creates inconsistent UI components.
Solution
Create an entire family together.
flowchart TD
A[Client]
A --> B[GUI Factory]
B --> C[Button]
B --> D[Textbox]
B --> E[Checkbox]
Abstract Factory Structure
classDiagram
class GUIFactory {
<<interface>>
+createButton()
+createTextbox()
}
class WindowsFactory
class MacFactory
class Button
class Textbox
GUIFactory <|.. WindowsFactory
GUIFactory <|.. MacFactory
WindowsFactory --> Button
WindowsFactory --> Textbox
MacFactory --> Button
MacFactory --> Textbox
Step 1: Create Product Interfaces
Button
public interface Button {
void render();
}
TextBox
public interface TextBox {
void render();
}
Step 2: Create Windows Products
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Windows Button Rendered");
}
}
public class WindowsTextBox implements TextBox {
@Override
public void render() {
System.out.println("Windows TextBox Rendered");
}
}
Step 3: Create Mac Products
public class MacButton implements Button {
@Override
public void render() {
System.out.println("Mac Button Rendered");
}
}
public class MacTextBox implements TextBox {
@Override
public void render() {
System.out.println("Mac TextBox Rendered");
}
}
Step 4: Create Abstract Factory
public interface GUIFactory {
Button createButton();
TextBox createTextBox();
}
Step 5: Create Concrete Factories
Windows Factory
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextBox createTextBox() {
return new WindowsTextBox();
}
}
Mac Factory
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextBox createTextBox() {
return new MacTextBox();
}
}
Step 6: Client Code
public class Application {
private final Button button;
private final TextBox textBox;
public Application(GUIFactory factory) {
button = factory.createButton();
textBox = factory.createTextBox();
}
public void renderUI() {
button.render();
textBox.render();
}
}
Main Method
public class Demo {
public static void main(String[] args) {
GUIFactory factory = new WindowsFactory();
Application app = new Application(factory);
app.renderUI();
}
}
Output
Windows Button Rendered
Windows TextBox Rendered
Object Creation Flow
sequenceDiagram
participant Client
participant WindowsFactory
participant WindowsButton
participant WindowsTextBox
Client->>WindowsFactory:createButton()
WindowsFactory-->>Client:WindowsButton
Client->>WindowsFactory:createTextBox()
WindowsFactory-->>Client:WindowsTextBox
Banking Example
Suppose a bank offers products.
Savings Family:
Savings Account
Savings Debit Card
Savings Rewards
Premium Family:
Premium Account
Premium Debit Card
Premium Rewards
Abstract Factory creates the entire family together.
Banking Diagram
flowchart TD
A[Bank Factory]
A --> B[Savings Products]
A --> C[Premium Products]
B --> D[Savings Account]
B --> E[Savings Card]
C --> F[Premium Account]
C --> G[Premium Card]
Insurance Example
Insurance Products:
Health Package
Health Policy
Health Claims
Health Premium Calculator
Vehicle Package
Vehicle Policy
Vehicle Claims
Vehicle Premium Calculator
Each package is a family of related products.
Cloud Provider Example
Enterprise systems often support:
AWS
Azure
GCP
Abstract Factory can create:
AWS Factory
EC2 Client
S3 Client
RDS Client
Azure Factory
VM Client
Blob Storage Client
SQL Client
Cloud Architecture
flowchart TD
A[Cloud Factory]
A --> B[AWS Factory]
A --> C[Azure Factory]
B --> D[EC2]
B --> E[S3]
C --> F[VM]
C --> G[Blob Storage]
Spring Framework Example
Spring internally uses factory concepts extensively.
Examples:
ApplicationContext
BeanFactory
FactoryBean
FactoryBean Example
@Component
public class CustomerFactoryBean
implements FactoryBean<Customer> {
@Override
public Customer getObject() {
Customer customer = new Customer();
customer.setName("CodeWithVenu");
return customer;
}
@Override
public Class<?> getObjectType() {
return Customer.class;
}
}
Spring creates objects through factory mechanisms behind the scenes.
Factory Method vs Abstract Factory
| Feature | Factory Method | Abstract Factory |
|---|---|---|
| Creates | One Product | Product Family |
| Complexity | Simple | Moderate |
| Number of Objects | One | Multiple |
| Use Case | Notification Type | UI Component Family |
Factory Method Example
Notification Factory
EMAIL
SMS
PUSH
Creates one notification object.
Abstract Factory Example
Windows Factory
Windows Button
Windows Textbox
Windows Checkbox
Creates a family of related objects.
Benefits
✅ Consistent Product Families
✅ Loose Coupling
✅ Easy To Extend
✅ Follows Open Closed Principle
✅ Centralized Object Creation
✅ Cleaner Code
Limitations
❌ More Classes
❌ More Complexity
❌ Overkill For Small Projects
❌ Harder To Understand Initially
When To Use
Use Abstract Factory when:
- Multiple product families exist
- Related objects must work together
- Object creation is complex
- Families may change dynamically
Examples:
- UI Frameworks
- Cloud Providers
- Banking Products
- Insurance Products
- Database Providers
When Not To Use
Avoid Abstract Factory when:
- Only one object needs creation
- Product families don't exist
- Simpler Factory Method is sufficient
Interview Questions
What is Abstract Factory?
A Creational Design Pattern that creates families of related objects without specifying concrete classes.
Difference Between Factory Method and Abstract Factory?
Factory Method creates one object.
Abstract Factory creates a family of related objects.
Give Real World Example
Windows UI Factory:
- Button
- TextBox
- Checkbox
Mac UI Factory:
- Button
- TextBox
- Checkbox
Is Abstract Factory Used In Spring?
Yes.
Examples include:
- BeanFactory
- FactoryBean
- ApplicationContext
Key Takeaways
- Abstract Factory creates families of related objects.
- It provides consistency across products.
- It hides complex object creation logic.
- It promotes loose coupling.
- Widely used in enterprise systems and frameworks.
- Factory Method creates one object.
- Abstract Factory creates multiple related objects together.