When you have FAMILIES of related objects that must be used together (e.g., "dark theme" = DarkButton + DarkPanel + DarkText). You don't want DarkButton mixed with LightPanel. Abstract Factory lets you create entire families through one interface.
// ─── EXAMPLE 1 ──────────────────────────────────────────────────────────────
// WHAT WE ARE IMPLEMENTING:
// A cross-platform UI theme manager supporting Dark and Light skins
// consistently.
//
// WHERE THE PATTERN FITS IN:
// ThemeFactory acts as the Abstract Factory. DarkThemeFactory and
// LightThemeFactory are Concrete Factories creating matching Button and
// Checkbox products.
// ────────────────────────────────────────────────────────────────────────────
// --- Product interfaces ---
interface Button { void render(); }
interface Checkbox { void render(); }
interface ThemeFactory {
Button createButton();
Checkbox createCheckbox();
}
// --- Dark theme family ---
class DarkButton implements Button {
public void render() { System.out.println(" [DarkButton] Rendered with dark bg"); }
}
class DarkCheckbox implements Checkbox {
public void render() { System.out.println(" [DarkCheckbox] Rendered dark"); }
}
class DarkThemeFactory implements ThemeFactory {
public Button createButton() { return new DarkButton(); }
public Checkbox createCheckbox() { return new DarkCheckbox(); }
}
// --- Light theme family ---
class LightButton implements Button {
public void render() { System.out.println(" [LightButton] Rendered with light bg"); }
}
class LightCheckbox implements Checkbox {
public void render() { System.out.println(" [LightCheckbox] Rendered light"); }
}
class LightThemeFactory implements ThemeFactory {
public Button createButton() { return new LightButton(); }
public Checkbox createCheckbox() { return new LightCheckbox(); }
}
class Application {
private final Button button;
private final Checkbox checkbox;
public Application(ThemeFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
void render() {
button.render();
checkbox.render();
}
}
public class Main {
public static void main(String[] args) {
// Choose family once — all products are consistent
Application app = new Application(new DarkThemeFactory());
app.render();
}
}