Singleton Design Pattern, Author: Majid Ahmaditabar
Singleton Design Pattern

Singleton Design pattern

Majid Ahmaditabar

--

The singleton pattern is a software design pattern that restricts the instantiation of a class to one “single” instance. This is useful when exactly one object is needed to coordinate actions across the system. The term comes from the mathematical concept of a singleton.

Critics consider the singleton to be an anti-pattern in that it is frequently used in scenarios where it is not beneficial, introduces unnecessary restrictions in situations where a sole instance of a class is not actually required, and introduces global state into an application.

What is Singleton?

Singleton is a creational design pattern that lets you ensure that a class has only one instance, while providing a global access point to this instance.The Singleton pattern solves two problems at the same time, violating the Single Responsibility Principle:

  • Ensure that a class has just a single instance:

The most common reason for this is to control access to some shared resource for example, a database or a file.Note that this behavior is impossible to implement with a regular constructor since a constructor call must always return a new object by design.

  • Provide a global access point to that instance.

Just like a global variable, the Singleton pattern lets you access some object from anywhere in the program. However, it also protects that instance from being overwritten by other code.

Nowadays, the Singleton pattern has become so popular that people may call something a singleton even if it solves just one of the listed problem

Use The Singleton Pattern :

  • There must be one and only one instance of a class
  • The class must be accessible to clients
  • The class should not require parameters as a part of its construction
  • When creating instance is expensive, a singleton can improve performance.

Solution

All implementations of the Singleton have these two steps in common:

  • Make the default constructor private, to prevent other objects
  • from using the new operator with the Singleton class.
  • Create a static creation method that acts as a constructor. Under the hood, this method calls the private constructor to create an object and saves it in a static field. All following calls to this method return the cached object.

Problem: Logger

we have a simple logger that we save message and date as a log to our logs file.

//typescript
class Logger {
logs: any

constructor() {
this.logs = [];
}

get_log() {
// return all logs
return this.logs;
}

set_log(message: string) {
// save message to logger
// it can be file or database
this.logs.push(message)
}
}

class LoggerSingleton {
static instance: Logger;

constructor() {
if (!LogSingleton.instance) {
LogSingleton.instance = new Logger;
}
}

get_instance() {
return LogSingleton.instance
}
}
// this line always call the same instance of Loggerlet logger = new LogSingleton().get_instance()logger.set_log('Example Massage')logger.get_log()

in this example ‘LoggerSingleton’ set instance of ‘Logger’ and then we have only one instance of our Logger everywhere.

Singletone in Node.js

in the Node.js just add the `module.exports` with new instance of the class then automatically build just one instance in our program.

class Logger {

constructor() {
this.logs = [];
}

get_log() {
// return all logs
return this.logs;
}

set_log(message: string) {
// save message to logger
// it can be file or database
this.logs.push(message)
}
}
module.exports = new Logger()

Problem: Database Connection

we want to connect to database in our app once and use it.it means when we want to database instance we just call same instance.

class Database {
// The field for storing the singleton instance should be
// declared static.

private static instance: Database

// The singleton's constructor should always be private to
// prevent direct construction calls with the `new`
// operator.

private constructor(){
}

// The static method that controls access to the singleton
//instance
public static getInstance() {
if (this.instance == null) {
this.instance = new Database()
}
return this.instance
}

// Finally, any singleton should define some business logic
// which can be executed on its instance.
public query(sql) {
// For instance, all database queries of an app go
// through this method. Therefore, you can place
// throttling or caching logic here.
// ...
}
}
class Application {
main() {
Database foo = Database.getInstance()
foo.query("SELECT ...")
// ...
Database bar = Database.getInstance()
bar.query("SELECT ...")
// The variable `bar` will contain the same object as
// the variable `foo`.
}
}

Pros

  • You can be sure that a class has only a single instance.
  • You gain a global access point to that instance.
  • The singleton object is initialized only when it’s requested for the first time.

Cons

  • Violates the Single Responsibility Principle. The pattern solves two problems at the time.
  • The Singleton pattern can mask bad design, for instance, when the components of the program know too much about each other.
  • The pattern requires special treatment in a multithreaded environment so that multiple threads won’t create a singleton object several times.
  • It may be difficult to unit test the client code of the Single- ton because many test frameworks rely on inheritance when producing mock objects. Since the constructor of the single- ton class is private and overriding static methods is impossible in most languages, you will need to think of a creative way to mock the singleton. Or just don’t write the tests. Or don’t use the Singleton pattern.

References

--

--