โ 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