Singleton

Singleton Pattern

Introduction

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. This pattern is particularly useful in scenarios where exactly one instance of a class is needed to coordinate actions across the system.

Purpose

  • Ensures that a class has only one instance.
  • Provides a global point of access to that instance.

Use Cases

  • Managing a connection to a database.
  • Implementing a logging class that writes to a single file.
  • Managing access to a shared resource, like a configuration object.

Advantages/Disadvantages

Advantages:

  • Controlled access to a single instance.
  • Reduced namespace pollution.
  • Lazy initialization, where the instance is created when needed.

Disadvantages:

  • Can be difficult to unit test due to global state.
  • Could lead to scalability issues in a multi-threaded context.
  • Overuse of singletons can lead to an anti-pattern, making code tightly coupled and hard to refactor.

Implementation in JavaScript

javascript
	let instance;
	
	class Singleton {
	  constructor() {
	    if (!instance) {
	      instance = this;
	    }
	    // Additional initialization can be done here.
	    return instance;
	  }
	
	  // Method on the singleton class
	  someMethod() {
	    // Implementation here
	  }
	}
	
	// Usage
	const singleton1 = new Singleton();
	const singleton2 = new Singleton();
	
	console.log(singleton1 === singleton2); // true, both variables point to the same instance

Practical Example

javascript
	let databaseInstance;
	
	class Database {
	  constructor(connectionString) {
	    if (!databaseInstance) {
	      databaseInstance = this;
	      this.connectionString = connectionString;
	      // Here you might initialize the database connection.
	    }
	    return databaseInstance;
	  }
	
	  // Method to get the database connection string
	  getConnection() {
	    return this.connectionString;
	  }
	}
	
	// Usage
	const db1 = new Database('Server=127.0.0.1;Database=MyDatabase;');
	const db2 = new Database('Server=192.168.1.1;Database=OtherDatabase;');
	
	console.log(db1.getConnection()); // Output will be "Server=127.0.0.1;Database=MyDatabase;"
	console.log(db1 === db2); // true, both variables point to the same instance despite different initial inputs

In this example, no matter how many times you instantiate a Database object, it ensures that only one instance ever exists, and all references point to the same instance.