The Singleton design pattern is a creational pattern that ensures a class has only one instance while providing a global point of access to that instance. This is useful when exactly one object is needed to coordinate actions across the system.
Key Points:
- Single Instance: Ensures that a class has only one instance.
- Global Access: Provides a global point of access to the instance.
- Lazy Initialization: The instance is created only when it is needed.
When to Use:
- Logging: A single logging instance to manage logs across the application.
- Configuration: A single configuration instance to manage application settings.
- Database Connection: A single database connection instance to manage database operations.
- Thread Pool: A single thread pool instance to manage threads.
Example in TypeScript:
class Singleton {
private static instance: Singleton;
private constructor() {
// Initialization code here
}
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
public someMethod(): void {
console.log("Method called on the singleton instance.");
}
}
// Usage
const singletonInstance1 = Singleton.getInstance();
const singletonInstance2 = Singleton.getInstance();
if (singletonInstance1 === singletonInstance2) {
console.log("Both instances are the same.");
}
singletonInstance1.someMethod();
Explanation:
- Private Constructor: The constructor is private to prevent direct instantiation.
- Static Instance: A static variable
instanceholds the single instance of the class. - getInstance Method: The
getInstancemethod checks if the instance is already created. If not, it creates one and returns it.
Use Cases:
- Logging:
class Logger {
private static instance: Logger;
private constructor() {
// Initialization code here
}
public static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
public log(message: string): void {
console.log(`LOG: ${message}`);
}
}
// Usage
const logger = Logger.getInstance();
logger.log("This is a log message.");
2.Configuration:
class Config {
private static instance: Config;
private settings: { [key: string]: any };
private constructor() {
this.settings = {};
}
public static getInstance(): Config {
if (!Config.instance) {
Config.instance = new Config();
}
return Config.instance;
}
public set(key: string, value: any): void {
this.settings[key] = value;
}
public get(key: string): any {
return this.settings[key];
}
}
// Usage
const config = Config.getInstance();
config.set("apiUrl", "https://api.example.com");
console.log(config.get("apiUrl"));
3. Database Connection:
class Database {
private static instance: Database;
private connection: any;
private constructor() {
this.connection = this.createConnection();
}
public static getInstance(): Database {
if (!Database.instance) {
Database.instance = new Database();
}
return Database.instance;
}
private createConnection(): any {
// Logic to create a database connection
return {};
}
public getConnection(): any {
return this.connection;
}
}
// Usage
const db = Database.getInstance();
const connection = db.getConnection();
The Singleton pattern is useful for scenarios where a single instance of a class is required to manage shared resources or coordinate actions across the system. It ensures that the instance is created only once and provides a global point of access to it.
Leave a Reply