A design pattern is a term used in software engineering for a general reusable solution to a commonly occurring problem in software design.

  1. Module Pattern
  2. Factory Pattern
  3. Observer Pattern
  4. Singleton Pattern

◉ Module Pattern

The Module Pattern is one of the important patterns in JavaScript. It is a commonly used Design Pattern which is used to wrap a set of variables and functions together in a single scope.

Modules should be Immediately-Invoked-Function-Expressions (IIFE) to allow for private scopes — that is, a closure that protect variables and methods (however, it will return an object instead of a function). This is what it looks like:

Syntax:

Data Hiding with the Module Pattern

Now let’s see how we can use the salary value without needing to expose it publicly:

The salary here is a sort of private variable that can be accessed by other functions that are exposed publicly from the function. It can be equivalent to a private hidden variable that is accessible by its member function. Hence providing the idea of data hiding.

Use Module pattern for the following benefits:

  1. Maintainability
  2. Reusability
  3. Loose Coupling to ensure NO dependency

◉ Factory Pattern

A factory function is any function that returns an object. Yup, that’s pretty much it. This is not to be confused with classes and constructor functions. Classes and constructor functions require the new keyword to instantiate objects while factory functions return the instantiated object itself.

factory pattern enables you to call a factory method — specified in an interface or implemented in a base class — which handles the creation of objects instead of a constructor.

By calling a factory method you avoid reallocating memory for each object you create, instead a factory method does that only once when it’s called.

To put it simply, our factory method is a centralized place or better yet, a factory that manufactures different types of objects.

  1. Use the Factory Method when you don’t know beforehand the exact types and dependencies of the objects your code should work with.
  2. Use the Factory Method when you want to save system resources by reusing existing objects instead of rebuilding them each time. You often experience this need when dealing with large, resource-intensive objects such as database connections, file systems, and network resources.

Using Closures for Private Variables

We now have all the knowledge needed to emulate “private” variables in JavaScript. We can begin by writing a factory function that returns an object with getter and setter methods. The factory function takes in two arguments that correspond to the “private” properties of the returned object.

function createAnimal(name, job) {
// "Private" variables here
let _name = name;
let _job = job;
// Public variables here
return {
// Getter Methods
getName() {
return _name;
},
getJob() {
return _job;
},
// Setter Methods
setName(newName) {
_name = newName;
},
setJob(newJob) {
_job = newJob;
}
};
}

We can then invoke the factory function to create new instances of an animal object. Note that every time we invoke the factory function, a new closure is created. Therefore, each returned object has access to its own closure.

const presto = createAnimal('Presto', 'Digger');
const fluffykins = createAnimal('Fluffykins', 'Jumper');

So what have we achieved by doing this? Well, with the power of closures, we have essentially emulated “private” variables in JavaScript.

// These properties will be inaccessible
console.log(presto._name); // undefined
console.log(presto._job); // undefined
console.log(fluffykins._name); // undefined
console.log(fluffykins._job); // undefined
// Getter methods have access to the closure
console.log(presto.getName()); // 'Presto'
console.log(presto.getJob()); // 'Digger'
console.log(fluffykins.getName()); // 'Fluffykins'
console.log(fluffykins.getJob()); // 'Jumper'
// Setter methods can mutate the variables in the closure
presto.setName('Quick');
presto.setJob('Bone Finder');
fluffykins.setName('Mittens');
fluffykins.setJob('Fish Eater');
console.log(presto.getName()); // 'Quick'
console.log(presto.getJob()); // 'Bone Finder'
console.log(fluffykins.getName()); // 'Mittens'
console.log(fluffykins.getJob()); // 'Fish Eater'

◉ Observer Pattern

The Observer Pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes.

◉ Singleton Pattern

The Singleton restricts clients from creating multiple objects, after the first object is created, it will return instances of itself i.e., A Singleton only allows for a single instantiation, but many instances of the same object.

For example, think of an e-commerce application where we have a ShoppingCart class. We need one and only one instance of that class throughout the application. There is no need to have multiple carts for a single user.

In AngularJS, Singletons are prevalent, the most notable being services, factories, and providers. Since they maintain state and provides resource accessing, creating two instances defeats the point of a shared service/factory/provider.

Race conditions occur in multi-threaded applications when more than one thread tries to access the same resource. Singletons are susceptible to race conditions, such that if no instance were initialised first, two threads could then create two objects instead of returning and instance. This defeats the purpose of a singleton. Therefore, developers must be privy to synchronisation when implementing singletons in multithreaded applications.

Design Patterns in React

React follows UNI-directional data flow.

Reference:

https://dev.to/somedood/emulating-private-variables-in-javascript-with-closures-and-factory-functions-2314

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.