โ† Back to Design Patterns
๐Ÿ”’
Creational

Singleton

Ensures a class has only one instance and provides a global access point to it.

The Problem

Some resources โ€” database connections, configuration, caches โ€” should exist only once. Without Singleton, calling `new Manager()` in multiple places creates separate instances that can get out of sync.

How It Works

  • โ€บOnly one instance exists for the entire application lifetime
  • โ€บLazy initialization: the instance is created on first access
  • โ€บThread safety is required in concurrent environments โ€” use dispatch queues or synchronized blocks
  • โ€บDifficult to unit-test because it carries global state across tests
  • โ€บPrefer dependency injection over Singleton where testability matters

When to Use

โœ“Shared resources like a database connection, logger, or analytics tracker
โœ“Configuration managers that should read settings only once
โœ“In-memory cache shared across the whole app
โœ“Hardware interface wrappers (serial port, Bluetooth manager)

Real-World Examples

๐ŸŽ
iOS

URLSession.shared, UserDefaults.standard, NotificationCenter.default

๐Ÿค–
Android

Room database instance, Retrofit client, SharedPreferences

๐ŸŒ
Web

Database connection pool, logger instance, event bus

Code Examples

Swift
final class AppSettings {
    static let shared = AppSettings()
    private init() {}   // prevents external instantiation

    var theme: String = "light"
    var language: String = "en"
}

// Usage โ€” always the same instance
AppSettings.shared.theme = "dark"
print(AppSettings.shared.theme) // "dark"

// Real-world equivalents:
// URLSession.shared
// UserDefaults.standard
// NotificationCenter.default