JS and Design patterns - Chapter 2 🚀
Tags: javascript, programming, codequality, webdev
Published: 2021-01-21 20:04:15

# 🤓 INTRODUCTION

Welcome, dear coders! I am really glad that you are interested in this kind of content. Here we are, at the second chapter of the Design Patterns explained using JavaScript programming language series. If you missed the previous introductory chapter of this series, please check it out at the link below!

{% link https://dev.to/codespresso/javascript-design-patterns-chapter-1-41bf %}

In this article, we will discuss another design pattern **The Singleton Pattern**.

# 🤷‍♂️ WHAT IS THE SINGLETON PATTERN?

Singleton is a creational design pattern that ensures that a class has only one instance.

![There can be only one](https://media.giphy.com/media/5rjEsJnmsUF2CxGg5e/giphy.gif)

Usually, the goal is to manage the global application state. To share data between the different parts of an application (components) that are not interconnected. You can find it being used as the source of config settings for a web app, on the client-side for anything initiated with an API key, and to store data in memory in a client-side web application such as Flux, Redux, or Vuex. Also, a singleton can be used as a singleton service (Like [Angular](https://angular.io/guide/singleton-services) does). When using it as a service, you manage that only one service instance exists in an app. Of course, those are all applications within a specific JavaScript library or platform such as Angular, React, or Vue.

❔ Since we're talking about JavaScript and its libraries and platforms, I would really like to know what is your preferred library/platform? (comment out which one and why 😉)

# ⚒ IMPLEMENTATION

Real-World application using simplified [Load Balancer logic](https://en.wikipedia.org/wiki/Load_balancing_(computing))
```javascript
//Simplified load balancer
var loadBalancer = (function() {
    // this is the unique
    // load balancer instance variable
    var loadBalancerInstance;
    // load balancer available servers 
    const servers = [];
    // function that 
    //will create the load balancer (assign servers) ONLY once
    function create() {
        servers.push("SERVER I");
        servers.push("SERVER II");
        servers.push("SERVER III");
        servers.push("SERVER IV");
        return servers;
    }

    //function for getting random server
    function getServer() {
        return Math.floor(Math.random() * loadBalancerInstance) + 1;
    }

    return {
        /*function that 
        will either create or 
        not create a new 
        load balancer instance */
        getInstance: function() {
            //if the load balancer 
            //instance is null or undefined, the load balancer 
            //will be created!
            if (!loadBalancerInstance) {
                loadBalancerInstance = create();
            } //if the load balancer is already created we just return an existing instance

            return loadBalancerInstance;
        }
    };
})();
//trying to create the 
//load balancer instance - Success
var balancer_0 = loadBalancer.getInstance();
//trying to create the
//load balancer instance
// - Error - Instance is already created
//previously created instance is assigned to any  
//of the following variable
//add as many as you want

var balancer_1 = loadBalancer.getInstance();
var balancer_2 = loadBalancer.getInstance();

/*Check if we are not wrong if 
all variables are the 
same instance print 
out fancy console.log with the
appropriate message
if variables are not the same 
instance print out the fancy console.log
with the appropriate message*/

if (balancer_0 === balancer_1 && balancer_0 === balancer_2) {
    console.log('%c%s', 'color: white; background: lightgreen; font-size: 24px;', 'Balancers are the same instance!')
} else {
    console.log('%c%s', 'color: black; background: red; font-size: 24px;', 'Balancers are not the same instance!')
}
```
💡 The singleton is not freed until the termination of the program


# 🧐 DISCUSSION

The Singleton design pattern is a very specific type of single instance, specifically one that is:

- Accessible via a global, static instance field;
- Created either on program initialization or upon first access;
- No public constructor (cannot instantiate directly);
- Never explicitly freed (implicitly freed on program termination).

It is because of this specific design choice that the pattern introduces several potential long-term problems:

- Inability to use abstract or interface classes;
- Inability to subclass;
- High coupling across the application (difficult to modify);
- Difficult to test (can't fake/mock in unit tests);
- Difficult to parallelize in the case of mutable state (requires extensive locking);

*In JavaScript, Singletons serve as a shared resource namespace that isolates implementation code from the global namespace so as to provide a single point of access for functions.*

# ✅ 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 Principal](https://en.wikipedia.org/wiki/Single-responsibility_principle#:~:text=The%20single%2Dresponsibility%20principle%20(SRP,functionality%2C%20which%20it%20should%20encapsulate.)
- 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 Singleton because many test frameworks rely on inheritance when producing mock objects. Since the constructor of the Singleton 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.



> *Whilst the Singleton has valid uses, often when we find ourselves needing it in JavaScript it's a sign that we may need to re-evaluate our design.&

> *They're often an indication that modules in a system are either tightly coupled or that logic is overly spread across multiple parts of a codebase. Singletons can be more difficult to test due to issues ranging from hidden dependencies, the difficulty in creating multiple instances, difficulty in stubbing dependencies, and so on.*

# 🙏 THANK YOU FOR READING!
Please leave the comment, tell me about you, about your work, comment your thoughts, connect with me via  [Twitter](https://twitter.com/lazar_dev) or  [LinkedIn](https://www.linkedin.com/in/lazar-stankovic-44a199177/). 

Let this year be your year, let this year be our year. Until the next typing...

Have a nice time!

References:
[robdodson](https://robdodson.me/javascript-design-patterns-singleton/)
[addyosmani](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript)
[refactoring](https://refactoring.guru/design-patterns/singleton)
School notes...

☕ SUPPORT ME AND KEEP ME FOCUSED!
<a href='https://ko-fi.com/Z8Z33D1HJ' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi4.png?v=2' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
😊