← Back to All Design Patterns

Abstract Factory Pattern

🎯 Explain Like I'm 5...

Imagine you have two different furniture factories: one makes Modern furniture and one makes Victorian furniture!

🏭 The Magic of Factories:

Modern Furniture Factory:

  • Makes a sleek, simple chair 🪑
  • Makes a glass table with metal legs 🔲

Victorian Furniture Factory:

  • Makes a fancy chair with carvings 👑
  • Makes a wooden table with decorations 🎨

🌟 The Key Idea:

Both factories know how to make a chair and a table, but each makes them in their own style! You can ask any factory for furniture, and you'll get matching pieces!

🚀 Why Is This Useful?

  • All your furniture matches - no mixing modern chairs with Victorian tables!
  • You can easily switch from modern to Victorian style by changing the factory!
  • Adding a new style (like 'Art Deco') is easy - just make a new factory!

🎯 Pattern Purpose

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It ensures that products created together belong to the same family and are compatible with each other.

📋 When to Use Abstract Factory

  • Your system needs to work with multiple families of related products
  • You want to ensure products from the same family are used together
  • You want to provide a library of products revealing only interfaces, not implementations
  • You need to configure your system with one of multiple families of products

🌍 Real-World Examples

  • 🖥️Cross-Platform UI Toolkits: Windows vs macOS buttons, scrollbars, and dialogs
  • 🗄️Database Connectors: MySQL vs PostgreSQL connections, statements, and result sets
  • 🎨Theme Systems: Light vs Dark theme colors, fonts, and icons
  • 📄Document Formats: PDF vs Word document elements and formatters

💻 Java Implementations

Example 1: GUI Framework (Windows vs Mac)

Creating cross-platform user interface components that look native on each operating system.

Button.java
java
1
2
3
4
5
6
// Abstract Product: Button
// This interface defines what all buttons must be able to do
public interface Button {
void paint(); // Draw the button on screen
void onClick(); // Handle button click
}
Checkbox.java
java
1
2
3
4
5
6
// Abstract Product: Checkbox
// This interface defines what all checkboxes must be able to do
public interface Checkbox {
void paint(); // Draw the checkbox on screen
void onCheck(); // Handle checkbox check/uncheck
}
Scrollbar.java
java
1
2
3
4
5
6
// Abstract Product: Scrollbar
// This interface defines what all scrollbars must be able to do
public interface Scrollbar {
void paint(); // Draw the scrollbar on screen
void onScroll(); // Handle scrolling action
}
WindowsButton.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Concrete Product: Windows Button
// This is how a button looks and behaves on Windows
public class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("Rendering a button in Windows style");
System.out.println(" [ Windows Button ]");
}
@Override
public void onClick() {
System.out.println("Windows button clicked!");
}
}
WindowsCheckbox.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Concrete Product: Windows Checkbox
// This is how a checkbox looks and behaves on Windows
public class WindowsCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Rendering a checkbox in Windows style");
System.out.println(" [ ] Windows Checkbox");
}
@Override
public void onCheck() {
System.out.println("Windows checkbox toggled!");
}
}
WindowsScrollbar.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Concrete Product: Windows Scrollbar
// This is how a scrollbar looks and behaves on Windows
public class WindowsScrollbar implements Scrollbar {
@Override
public void paint() {
System.out.println("Rendering a scrollbar in Windows style");
System.out.println(" [|||] Windows Scrollbar");
}
@Override
public void onScroll() {
System.out.println("Windows scrollbar scrolled!");
}
}
MacButton.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Concrete Product: Mac Button
// This is how a button looks and behaves on macOS
public class MacButton implements Button {
@Override
public void paint() {
System.out.println("Rendering a button in Mac style");
System.out.println(" ( Mac Button )");
}
@Override
public void onClick() {
System.out.println("Mac button clicked!");
}
}
MacCheckbox.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Concrete Product: Mac Checkbox
// This is how a checkbox looks and behaves on macOS
public class MacCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Rendering a checkbox in Mac style");
System.out.println(" Mac Checkbox");
}
@Override
public void onCheck() {
System.out.println("Mac checkbox toggled!");
}
}
MacScrollbar.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Concrete Product: Mac Scrollbar
// This is how a scrollbar looks and behaves on macOS
public class MacScrollbar implements Scrollbar {
@Override
public void paint() {
System.out.println("Rendering a scrollbar in Mac style");
System.out.println(" [:::] Mac Scrollbar");
}
@Override
public void onScroll() {
System.out.println("Mac scrollbar scrolled!");
}
}
GUIFactory.java
java
1
2
3
4
5
6
7
8
// Abstract Factory: GUIFactory
// This interface defines how to create a family of related GUI components
// Each concrete factory will create components that work well together
public interface GUIFactory {
Button createButton(); // Create a button for this platform
Checkbox createCheckbox(); // Create a checkbox for this platform
Scrollbar createScrollbar(); // Create a scrollbar for this platform
}
WindowsFactory.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Concrete Factory: Windows Factory
// This factory creates all Windows-style components
// All components created by this factory look and work like Windows
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
@Override
public Scrollbar createScrollbar() {
return new WindowsScrollbar();
}
}
MacFactory.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Concrete Factory: Mac Factory
// This factory creates all Mac-style components
// All components created by this factory look and work like macOS
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
@Override
public Scrollbar createScrollbar() {
return new MacScrollbar();
}
}
Application.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Client Code: Application
// This application works with any GUI factory
// It doesn't know if it's creating Windows or Mac components
public class Application {
private Button button;
private Checkbox checkbox;
private Scrollbar scrollbar;
// Constructor receives a factory - could be Windows or Mac!
public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
scrollbar = factory.createScrollbar();
}
// Paint all UI components
public void paint() {
button.paint();
checkbox.paint();
scrollbar.paint();
}
// Handle user interaction
public void interact() {
button.onClick();
checkbox.onCheck();
scrollbar.onScroll();
}
}
GUIDemo.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Demo: Using the GUI Abstract Factory
public class GUIDemo {
public static void main(String[] args) {
// Determine which operating system we're on
String osName = System.getProperty("os.name").toLowerCase();
GUIFactory factory;
// Choose the appropriate factory based on OS
if (osName.contains("windows")) {
System.out.println("Creating Windows GUI...\n");
factory = new WindowsFactory();
} else if (osName.contains("mac")) {
System.out.println("Creating Mac GUI...\n");
factory = new MacFactory();
} else {
System.out.println("Creating default (Windows) GUI...\n");
factory = new WindowsFactory();
}
// Create application with the chosen factory
Application app = new Application(factory);
System.out.println("Painting UI components:");
app.paint();
System.out.println("\nSimulating user interaction:");
app.interact();
System.out.println("\n--- Demonstrating Mac GUI ---\n");
// We can easily switch to Mac style by using MacFactory
Application macApp = new Application(new MacFactory());
macApp.paint();
macApp.interact();
}
}

Example 2: Theme System (Light vs Dark)

Building a theme system where all UI components match the selected theme.

Color.java
java
1
2
3
4
5
6
7
8
// Abstract Product: Color scheme
// Defines the color interface for theme components
public interface Color {
String getPrimaryColor(); // Main color for the theme
String getSecondaryColor(); // Accent color
String getBackgroundColor(); // Background color
String getTextColor(); // Text color
}
Font.java
java
1
2
3
4
5
6
7
// Abstract Product: Font settings
// Defines the font interface for theme components
public interface Font {
String getFontFamily(); // Font name (Arial, Times, etc.)
int getFontSize(); // Size in pixels
String getFontWeight(); // normal, bold, etc.
}
Icon.java
java
1
2
3
4
5
6
7
// Abstract Product: Icon set
// Defines the icon interface for theme components
public interface Icon {
String getHomeIcon(); // Home icon representation
String getSettingsIcon(); // Settings icon representation
String getProfileIcon(); // Profile icon representation
}
LightColor.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Concrete Product: Light theme colors
// Bright, easy-on-the-eyes colors for daytime use
public class LightColor implements Color {
@Override
public String getPrimaryColor() {
return "#2196F3"; // Blue
}
@Override
public String getSecondaryColor() {
return "#FFC107"; // Amber
}
@Override
public String getBackgroundColor() {
return "#FFFFFF"; // White
}
@Override
public String getTextColor() {
return "#000000"; // Black
}
}
LightFont.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Concrete Product: Light theme font
// Regular weight fonts for light backgrounds
public class LightFont implements Font {
@Override
public String getFontFamily() {
return "Roboto";
}
@Override
public int getFontSize() {
return 16;
}
@Override
public String getFontWeight() {
return "normal"; // Regular weight for light theme
}
}
LightIcon.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Concrete Product: Light theme icons
// Outlined icons that work well on light backgrounds
public class LightIcon implements Icon {
@Override
public String getHomeIcon() {
return "🏠 (outlined)"; // Simple outlined home
}
@Override
public String getSettingsIcon() {
return "⚙️ (outlined)"; // Simple outlined gear
}
@Override
public String getProfileIcon() {
return "👤 (outlined)"; // Simple outlined person
}
}
DarkColor.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Concrete Product: Dark theme colors
// Dark, comfortable colors for nighttime use
public class DarkColor implements Color {
@Override
public String getPrimaryColor() {
return "#BB86FC"; // Purple
}
@Override
public String getSecondaryColor() {
return "#03DAC6"; // Teal
}
@Override
public String getBackgroundColor() {
return "#121212"; // Almost black
}
@Override
public String getTextColor() {
return "#FFFFFF"; // White
}
}
DarkFont.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Concrete Product: Dark theme font
// Slightly lighter weight fonts for dark backgrounds
public class DarkFont implements Font {
@Override
public String getFontFamily() {
return "Roboto";
}
@Override
public int getFontSize() {
return 16;
}
@Override
public String getFontWeight() {
return "300"; // Light weight for dark theme (easier to read)
}
}
DarkIcon.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Concrete Product: Dark theme icons
// Filled icons that stand out on dark backgrounds
public class DarkIcon implements Icon {
@Override
public String getHomeIcon() {
return "🏠 (filled)"; // Solid filled home
}
@Override
public String getSettingsIcon() {
return "⚙️ (filled)"; // Solid filled gear
}
@Override
public String getProfileIcon() {
return "👤 (filled)"; // Solid filled person
}
}
ThemeFactory.java
java
1
2
3
4
5
6
7
8
// Abstract Factory: Theme Factory
// This interface defines how to create a complete theme
// Each theme has colors, fonts, and icons that work together
public interface ThemeFactory {
Color createColor(); // Create color scheme for this theme
Font createFont(); // Create font settings for this theme
Icon createIcon(); // Create icon set for this theme
}
LightThemeFactory.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Concrete Factory: Light Theme Factory
// Creates all components for a light, daytime theme
// All components are designed to work together
public class LightThemeFactory implements ThemeFactory {
@Override
public Color createColor() {
return new LightColor();
}
@Override
public Font createFont() {
return new LightFont();
}
@Override
public Icon createIcon() {
return new LightIcon();
}
}
DarkThemeFactory.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Concrete Factory: Dark Theme Factory
// Creates all components for a dark, nighttime theme
// All components are designed to work together
public class DarkThemeFactory implements ThemeFactory {
@Override
public Color createColor() {
return new DarkColor();
}
@Override
public Font createFont() {
return new DarkFont();
}
@Override
public Icon createIcon() {
return new DarkIcon();
}
}
UIRenderer.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Client Code: UI Renderer
// This class renders the UI using theme components
// It works with any theme without knowing which one it is
public class UIRenderer {
private Color color;
private Font font;
private Icon icon;
// Constructor receives a theme factory
public UIRenderer(ThemeFactory factory) {
this.color = factory.createColor();
this.font = factory.createFont();
this.icon = factory.createIcon();
}
// Render the user interface with current theme
public void render() {
System.out.println("=== Rendering UI ===");
System.out.println("Background: " + color.getBackgroundColor());
System.out.println("Text: " + color.getTextColor());
System.out.println("Primary: " + color.getPrimaryColor());
System.out.println("Secondary: " + color.getSecondaryColor());
System.out.println();
System.out.println("Font: " + font.getFontFamily() +
" " + font.getFontSize() + "px " +
font.getFontWeight());
System.out.println();
System.out.println("Icons:");
System.out.println(" Home: " + icon.getHomeIcon());
System.out.println(" Settings: " + icon.getSettingsIcon());
System.out.println(" Profile: " + icon.getProfileIcon());
System.out.println("===================\n");
}
}
ThemeDemo.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Demo: Using the Theme Abstract Factory
public class ThemeDemo {
public static void main(String[] args) {
// Simulate user preference or time of day
boolean isDarkMode = true;
System.out.println("Theme System Demo\n");
// Create appropriate theme factory based on preference
ThemeFactory factory;
if (isDarkMode) {
System.out.println("User prefers dark mode\n");
factory = new DarkThemeFactory();
} else {
System.out.println("User prefers light mode\n");
factory = new LightThemeFactory();
}
// Create UI renderer with chosen theme
UIRenderer renderer = new UIRenderer(factory);
renderer.render();
// Switching themes is easy - just create a new renderer with different factory
System.out.println("\n--- Switching to Light Theme ---\n");
UIRenderer lightRenderer = new UIRenderer(new LightThemeFactory());
lightRenderer.render();
System.out.println("\n--- Switching back to Dark Theme ---\n");
UIRenderer darkRenderer = new UIRenderer(new DarkThemeFactory());
darkRenderer.render();
}
}

Example 3: Vehicle Parts Factory (Car vs Truck)

Manufacturing vehicle parts where each vehicle type gets compatible components.

Engine.java
java
1
2
3
4
5
6
7
8
// Abstract Product: Engine
// All vehicles need an engine, but different types of engines
public interface Engine {
void start(); // Start the engine
void stop(); // Stop the engine
int getHorsepower(); // Get engine power
String getFuelType(); // Get fuel type (gasoline, diesel, etc.)
}
Tire.java
java
1
2
3
4
5
6
7
8
// Abstract Product: Tire
// All vehicles need tires, but different sizes and types
public interface Tire {
int getDiameter(); // Tire size in inches
String getTerrainType(); // Road, off-road, etc.
void inflate(); // Add air to tire
void checkPressure(); // Check tire pressure
}
Chassis.java
java
1
2
3
4
5
6
7
// Abstract Product: Chassis
// The frame/body of the vehicle
public interface Chassis {
String getMaterial(); // Steel, aluminum, etc.
int getWeightCapacity(); // Maximum load in kg
void inspect(); // Check chassis condition
}
CarEngine.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Concrete Product: Car Engine
// Smaller, efficient engine for passenger cars
public class CarEngine implements Engine {
@Override
public void start() {
System.out.println("Car engine starting with smooth purr...");
}
@Override
public void stop() {
System.out.println("Car engine stopping quietly...");
}
@Override
public int getHorsepower() {
return 150; // Moderate power for city driving
}
@Override
public String getFuelType() {
return "Gasoline";
}
}
CarTire.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Concrete Product: Car Tire
// Standard road tires for smooth highway driving
public class CarTire implements Tire {
@Override
public int getDiameter() {
return 17; // Inches - standard car tire size
}
@Override
public String getTerrainType() {
return "Paved roads";
}
@Override
public void inflate() {
System.out.println("Inflating car tire to 32 PSI...");
}
@Override
public void checkPressure() {
System.out.println("Car tire pressure is normal (32 PSI)");
}
}
CarChassis.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Concrete Product: Car Chassis
// Lightweight frame for passenger comfort
public class CarChassis implements Chassis {
@Override
public String getMaterial() {
return "Aluminum alloy"; // Lightweight for fuel efficiency
}
@Override
public int getWeightCapacity() {
return 500; // kg - passengers and luggage
}
@Override
public void inspect() {
System.out.println("Inspecting car chassis: Lightweight, no rust");
}
}
TruckEngine.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Concrete Product: Truck Engine
// Powerful, heavy-duty engine for hauling cargo
public class TruckEngine implements Engine {
@Override
public void start() {
System.out.println("Truck engine starting with deep rumble...");
}
@Override
public void stop() {
System.out.println("Truck engine stopping with vibration...");
}
@Override
public int getHorsepower() {
return 400; // High power for heavy loads
}
@Override
public String getFuelType() {
return "Diesel";
}
}
TruckTire.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Concrete Product: Truck Tire
// Large, durable tires for heavy loads
public class TruckTire implements Tire {
@Override
public int getDiameter() {
return 24; // Inches - large truck tire
}
@Override
public String getTerrainType() {
return "Highway and off-road";
}
@Override
public void inflate() {
System.out.println("Inflating truck tire to 80 PSI...");
}
@Override
public void checkPressure() {
System.out.println("Truck tire pressure is normal (80 PSI)");
}
}
TruckChassis.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Concrete Product: Truck Chassis
// Heavy-duty frame for cargo and durability
public class TruckChassis implements Chassis {
@Override
public String getMaterial() {
return "Reinforced steel"; // Strong for heavy loads
}
@Override
public int getWeightCapacity() {
return 5000; // kg - heavy cargo capacity
}
@Override
public void inspect() {
System.out.println("Inspecting truck chassis: Heavy-duty, very strong");
}
}
VehicleFactory.java
java
1
2
3
4
5
6
7
8
// Abstract Factory: Vehicle Parts Factory
// This interface defines how to create a complete set of vehicle parts
// Each vehicle type gets compatible parts designed to work together
public interface VehicleFactory {
Engine createEngine(); // Create engine for this vehicle type
Tire createTire(); // Create tire for this vehicle type
Chassis createChassis(); // Create chassis for this vehicle type
}
CarFactory.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Concrete Factory: Car Parts Factory
// Creates all parts needed to build a passenger car
// All parts are designed to work together efficiently
public class CarFactory implements VehicleFactory {
@Override
public Engine createEngine() {
return new CarEngine();
}
@Override
public Tire createTire() {
return new CarTire();
}
@Override
public Chassis createChassis() {
return new CarChassis();
}
}
TruckFactory.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Concrete Factory: Truck Parts Factory
// Creates all parts needed to build a cargo truck
// All parts are designed for heavy-duty performance
public class TruckFactory implements VehicleFactory {
@Override
public Engine createEngine() {
return new TruckEngine();
}
@Override
public Tire createTire() {
return new TruckTire();
}
@Override
public Chassis createChassis() {
return new TruckChassis();
}
}
Vehicle.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Client Code: Vehicle Assembly
// This class assembles a vehicle using parts from a factory
// It doesn't care if it's building a car or truck
public class Vehicle {
private Engine engine;
private Tire tire;
private Chassis chassis;
private String type;
// Constructor receives a factory and vehicle type
public Vehicle(VehicleFactory factory, String type) {
this.type = type;
this.engine = factory.createEngine();
this.tire = factory.createTire();
this.chassis = factory.createChassis();
}
// Display vehicle specifications
public void showSpecs() {
System.out.println("=== " + type + " Specifications ===");
System.out.println();
System.out.println("Engine:");
System.out.println(" Horsepower: " + engine.getHorsepower() + " HP");
System.out.println(" Fuel Type: " + engine.getFuelType());
System.out.println();
System.out.println("Tires:");
System.out.println(" Diameter: " + tire.getDiameter() + " inches");
System.out.println(" Terrain: " + tire.getTerrainType());
System.out.println();
System.out.println("Chassis:");
System.out.println(" Material: " + chassis.getMaterial());
System.out.println(" Weight Capacity: " + chassis.getWeightCapacity() + " kg");
System.out.println("========================\n");
}
// Test all vehicle components
public void test() {
System.out.println("Testing " + type + "...\n");
engine.start();
tire.inflate();
tire.checkPressure();
chassis.inspect();
engine.stop();
System.out.println();
}
}
VehicleDemo.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Demo: Using the Vehicle Abstract Factory
public class VehicleDemo {
public static void main(String[] args) {
System.out.println("Vehicle Manufacturing System\n");
System.out.println("============================\n");
// Build a car using CarFactory
System.out.println("Building a Car...\n");
VehicleFactory carFactory = new CarFactory();
Vehicle car = new Vehicle(carFactory, "Passenger Car");
car.showSpecs();
car.test();
System.out.println("\n" + "=".repeat(50) + "\n");
// Build a truck using TruckFactory
System.out.println("Building a Truck...\n");
VehicleFactory truckFactory = new TruckFactory();
Vehicle truck = new Vehicle(truckFactory, "Cargo Truck");
truck.showSpecs();
truck.test();
System.out.println("\n" + "=".repeat(50) + "\n");
// Key advantage: All parts are compatible
System.out.println("Key Benefit: All parts from the same factory are compatible!");
System.out.println("Car parts work together, truck parts work together.");
System.out.println("No mixing car engines with truck chassis!");
}
}

🔄 Abstract Factory vs Factory Method

These patterns are related but serve different purposes:

Factory Method:

  • Creates ONE type of product
  • Uses inheritance (subclasses decide which class to instantiate)
  • Example: Different types of pizzas

Abstract Factory:

  • Creates FAMILIES of related products
  • Uses composition (object delegates creation to factory object)
  • Example: Complete furniture sets (Modern set: chair + table + sofa)

🔑 Key Points to Remember

  • 1️⃣Abstract Factory creates families of related objects
  • 2️⃣Products from one factory are compatible with each other
  • 3️⃣Each concrete factory produces a complete set of products
  • 4️⃣Client code works with factories and products through abstract interfaces
  • 5️⃣Easy to add new product families, hard to add new product types
  • 6️⃣Ensures consistency among products created by the same factory

💪 Practice Scenarios

  • Create a Restaurant Menu Factory (Italian vs Chinese cuisine with appetizer, main course, dessert)
  • Implement a Game Character Factory (Warrior vs Mage with weapon, armor, skill)
  • Build a Report Generator Factory (PDF vs Excel with header, content, footer)
  • Design a Cloud Provider Factory (AWS vs Azure with storage, compute, database services)
  • Develop a Mobile UI Factory (iOS vs Android with button, input field, navigation bar)