Lesson Completion
Back to course

Creational Patterns: Object Creation Mechanisms

Beginner
12 minutes4.5Java

1. The Hook (The "Byte-Sized" Intro)

  • In a Nutshell: Creational patterns control object creation. Singleton = only one instance (database connection), Factory Method = subclass decides which class to instantiate, Abstract Factory = family of related objects, Builder = step-by-step construction (fluent API), Prototype = clone objects.
  • Benefits: Flexibility, decoupling, control.
  • Use: Singleton for shared resources, Factory for families of objects, Builder for complex objects, Prototype for expensive initialization!

Think of manufacturing. Singleton = one CEO (only one instance). Factory = car factory (choose sedan vs SUV). Abstract Factory = furniture set (modern vs Victorian, all match). Builder = custom PC (choose CPU, RAM, GPU step-by-step). Prototype = photocopier (clone documents)!


2. Conceptual Clarity (The "Simple" Tier)

💡 The Analogy

  • Singleton: Government president (one at a time)
  • Factory: Restaurant kitchen (orders → dishes)
  • Builder: LEGO instructions (step-by-step assembly)
  • Prototype: Copy machine (duplicate originals)

3. Technical Mastery (The "Deep Dive")

Creational Patterns Overview

PatternPurposeUse When
SingletonOne instance globallyShared resource (DB, logger)
Factory MethodDefer instantiation to subclassesProduct type varies
Abstract FactoryFamily of related objectsCross-platform UI
BuilderComplex object constructionMany optional parameters
PrototypeClone objectsExpensive initialization

4. Interactive & Applied Code

java
// =========================================== // 1. SINGLETON PATTERN // =========================================== // ❌ BAD: Not singleton class Database { Database() { // Expensive connection } } // Multiple instances = resource waste! // ✅ GOOD: Thread-safe singleton (Bill Pugh) class Database { private Database() {} private static class Holder { static final Database INSTANCE = new Database(); } public static Database getInstance() { return Holder.INSTANCE; // Lazy, thread-safe! } } // Usage: Database db1 = Database.getInstance(); Database db2 = Database.getInstance(); // db1 == db2 (same instance!) // ✅ BEST: Enum singleton enum DatabaseConnection { INSTANCE; public void connect() { System.out.println("Connected"); } } // Usage: DatabaseConnection.INSTANCE.connect(); // =========================================== // 2. FACTORY METHOD PATTERN // =========================================== // Product interface interface Vehicle { void drive(); } class Car implements Vehicle { public void drive() { System.out.println("Driving car"); } } class Truck implements Vehicle { public void drive() { System.out.println("Driving truck"); } } // Factory abstract class VehicleFactory { abstract Vehicle createVehicle(); void deliverVehicle() { Vehicle v = createVehicle(); v.drive(); } } class CarFactory extends VehicleFactory { Vehicle createVehicle() { return new Car(); } } class TruckFactory extends VehicleFactory { Vehicle createVehicle() { return new Truck(); } } // Usage: VehicleFactory factory = new CarFactory(); factory.deliverVehicle(); // Driving car // =========================================== // 3. ABSTRACT FACTORY PATTERN // =========================================== // Abstract products interface Button { void render(); } interface Checkbox { void render(); } // Concrete products (Windows) class WindowsButton implements Button { public void render() { System.out.println("Windows button"); } } class WindowsCheckbox implements Checkbox { public void render() { System.out.println("Windows checkbox"); } } // Concrete products (Mac) class MacButton implements Button { public void render() { System.out.println("Mac button"); } } class MacCheckbox implements Checkbox { public void render() { System.out.println("Mac checkbox"); } } // Abstract factory interface GUIFactory { Button createButton(); Checkbox createCheckbox(); } // Concrete factories class WindowsFactory implements GUIFactory { public Button createButton() { return new WindowsButton(); } public Checkbox createCheckbox() { return new WindowsCheckbox(); } } class MacFactory implements GUIFactory { public Button createButton() { return new MacButton(); } public Checkbox createCheckbox() { return new MacCheckbox(); } } // Usage: GUIFactory factory = new WindowsFactory(); // Or MacFactory Button btn = factory.createButton(); Checkbox chk = factory.createCheckbox(); // All components match the same family! // =========================================== // 4. BUILDER PATTERN // =========================================== // ❌ BAD: Telescoping constructor class User { String name; int age; String email; String phone; String address; User(String name) { this.name = name; } User(String name, int age) { this.name = name; this.age = age; } User(String name, int age, String email) { /* ... */ } // Too many constructors! } // ✅ GOOD: Builder pattern class User { private final String name; // Required private final int age; // Optional private final String email; // Optional private final String phone; // Optional private User(Builder builder) { this.name = builder.name; this.age = builder.age; this.email = builder.email; this.phone = builder.phone; } static class Builder { private final String name; // Required private int age; private String email; private String phone; Builder(String name) { this.name = name; } Builder age(int age) { this.age = age; return this; } Builder email(String email) { this.email = email; return this; } Builder phone(String phone) { this.phone = phone; return this; } User build() { return new User(this); } } } // Usage (fluent API): User user = new User.Builder("Alice") .age(30) .email("alice@example.com") .build(); // =========================================== // 5. PROTOTYPE PATTERN // =========================================== class Document implements Cloneable { String title; List<String> pages; Document(String title) { this.title = title; this.pages = new ArrayList<>(); // Expensive initialization loadTemplate(); } void loadTemplate() { // Expensive operation pages.add("Page 1"); pages.add("Page 2"); } @Override public Document clone() { try { Document cloned = (Document) super.clone(); cloned.pages = new ArrayList<>(this.pages); // Deep copy return cloned; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } } // Usage: Document original = new Document("Template"); // Expensive Document copy1 = original.clone(); // ✅ Fast! Document copy2 = original.clone(); // ✅ Fast! copy1.title = "Copy 1";

5. The Comparison & Decision Layer

PatternUse WhenExample
SingletonNeed exactly one instanceLogger, Config
FactoryProduct type variesDocument (PDF, Word)
Abstract FactoryFamily of productsGUI (Windows, Mac)
BuilderComplex object, many paramsHTTP Request, SQL Query
PrototypeExpensive initializationGame objects, Templates

6. The "Interview Corner" (The Edge)

The "Killer" Interview Question: "How to make Singleton thread-safe?" Answer: Multiple approaches!

java
// ❌ NOT thread-safe class Singleton { private static Singleton instance; static Singleton getInstance() { if (instance == null) { instance = new Singleton(); // Race condition! } return instance; } } // ✅ Bill Pugh (best) class Singleton { private static class Holder { static final Singleton INSTANCE = new Singleton(); } static Singleton getInstance() { return Holder.INSTANCE; // Lazy + thread-safe! } } // ✅ Enum (simplest, best) enum Singleton { INSTANCE; }

Pro-Tip: Builder for immutability:

java
// Immutable User with Builder class User { private final String name; // final = immutable private final int age; private User(Builder b) { this.name = b.name; this.age = b.age; } static class Builder { private String name; private int age; Builder name(String name) { this.name = name; return this; } User build() { return new User(this); } } } // Combines Builder pattern + immutability!

Topics Covered

Java Fundamentals

Tags

#java#programming#beginner-friendly

Last Updated

2025-02-01