codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Subjects
🧩

OOP Concepts

23 chapters

1Procedural vs Object-Oriented2Classes, Objects, & Instantiation3Constructors & Destructors4Static Members & Methods5Encapsulation & Access Modifiers6Data Abstraction7Inheritance Types (Single, Multiple)8Compile-Time Polymorphism (Overloading)9Polymorphism & Interfaces10Run-Time Polymorphism (Overriding)11Virtual Functions & V-Tables12Interfaces & Abstract Classes13Generic Programming (Templates & Generics)14Exception Handling in OOP15SOLID Design Principles16Composition over Inheritance17Coupling & Cohesion18UML Diagrams Basics19Creational Patterns (Singleton, Factory)20Structural Patterns (Adapter, Decorator)21Behavioral Patterns (Observer, Strategy)22MVC Architecture Pattern23Object Serialization & Cloning
SubjectsOOP Concepts

Creational Patterns (Singleton, Factory)

Updated 2026-04-26
2 min read

Creational Patterns (Singleton, Factory)

Design Patterns are proven, reusable solutions to commonly occurring problems in software design. They were formally cataloged in the 1994 book "Design Patterns: Elements of Reusable Object-Oriented Software" by the Gang of Four (GoF).

Creational Patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.

1. The Singleton Pattern

Intent: Ensure a class has only one instance, and provide a global point of access to it.

When to use it:

  • A database connection pool (you don't want 1,000 separate pools consuming memory).
  • A logging service (all parts of the application should write to the same log file).
  • A configuration manager (settings should be loaded once and shared globally).

Implementation:

class DatabaseConnection {
    // 1. Private static instance variable
    private static DatabaseConnection instance;

    // 2. Private constructor: Prevents external instantiation
    private DatabaseConnection() {
        System.out.println("Connecting to database...");
    }

    // 3. Public static method: The global access point
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }

    public void query(String sql) { /* execute query */ }
}

// Usage
DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();
// db1 and db2 point to the EXACT SAME object in memory.

Thread Safety Concern

The basic implementation above is NOT thread-safe. If two threads call getInstance() simultaneously when instance is null, both might create a new instance. Solutions include using synchronized, Double-Checked Locking, or the Bill Pugh Singleton (using a static inner class).

2. The Factory Method Pattern

Intent: Define an interface for creating objects, but let subclasses decide which class to instantiate.

When to use it:

  • When you don't know ahead of time the exact types of objects your code needs to create.
  • When you want to decouple the creation logic from the business logic.

The Problem:

Without a factory, the client code is tightly coupled to concrete classes:

// BAD: Client code is tightly coupled to specific notification types
if (type.equals("email")) {
    Notification n = new EmailNotification();
} else if (type.equals("sms")) {
    Notification n = new SMSNotification();
} else if (type.equals("push")) {
    Notification n = new PushNotification();
}

If you add a SlackNotification, you must find and modify this if-else chain everywhere in the codebase.

The Solution (Factory):

interface Notification {
    void send(String message);
}

class EmailNotification implements Notification {
    public void send(String msg) { System.out.println("Email: " + msg); }
}

class SMSNotification implements Notification {
    public void send(String msg) { System.out.println("SMS: " + msg); }
}

// The Factory: Centralizes all creation logic
class NotificationFactory {
    public static Notification create(String type) {
        return switch (type) {
            case "email" -> new EmailNotification();
            case "sms" -> new SMSNotification();
            default -> throw new IllegalArgumentException("Unknown type");
        };
    }
}

// Usage: Client code is decoupled from concrete classes
Notification n = NotificationFactory.create("email");
n.send("Hello!");

Now, adding a SlackNotification only requires modifying the single NotificationFactory class. All client code remains untouched.



PreviousUML Diagrams BasicsNextStructural Patterns (Adapter, Decorator)

Recommended Gear

UML Diagrams BasicsStructural Patterns (Adapter, Decorator)