Understanding Design Patterns in JavaScript: Singleton, Factory, and Observer Explained

Posted by

JavaScript Interview Question – What is Design Pattern ? [ Singleton Factory & Observer ]

JavaScript Interview Question – What is Design Pattern ?

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. It is a description or template for how to solve a problem that can be used in many different situations. In JavaScript, there are several design patterns that are commonly used to solve various problems.

Singleton Pattern

The Singleton pattern is a creational pattern that restricts the instantiation of a class to a single instance. This is useful when exactly one object is needed to coordinate actions across the system. Singleton patterns are often used for logging, drivers objects, caching, thread pools, or database connections. In JavaScript, a common implementation of the Singleton pattern is:

“`javascript
var Singleton = (function () {
var instance;

function createInstance() {
var object = new Object(“I am the instance”);
return object;
}

return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();

var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // Output: true
“`

Factory Pattern

The Factory pattern is another creational pattern which provides an interface for creating objects without specifying their concrete classes. It defines an interface for creating an object, but allows subclasses to alter the type of objects that will be created. In JavaScript, a common implementation of the Factory pattern is:

“`javascript
function Developer(name) {
this.name = name;
this.type = “Developer”;
}

function Tester(name) {
this.name = name;
this.type = “Tester”;
}

function EmployeeFactory() {
this.create = (name, type) => {
switch (type) {
case 1:
return new Developer(name);
case 2:
return new Tester(name);
}
};
}

const employeeFactory = new EmployeeFactory();
const employees = [];

employees.push(employeeFactory.create(“John”, 1));
employees.push(employeeFactory.create(“Jane”, 2));

console.log(employees); // Output: [ Developer { name: ‘John’, type: ‘Developer’ }, Tester { name: ‘Jane’, type: ‘Tester’ } ]
“`

Observer Pattern

The Observer pattern is a behavioral pattern that defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. This is useful for maintaining consistency between related objects. In JavaScript, a common implementation of the Observer pattern is:

“`javascript
function Observer() {
this.observers = [];
}

Observer.prototype = {
subscribe: function (fn) {
this.observers.push(fn);
},
unsubscribe: function (fn) {
this.observers = this.observers.filter((item) => item !== fn);
},
fire: function () {
this.observers.forEach((observer) => observer.call());
}
};

const subject = new Observer();

function observer1() {
console.log(“Observer 1 is fired!”);
}

function observer2() {
console.log(“Observer 2 is fired!”);
}

subject.subscribe(observer1);
subject.subscribe(observer2);
subject.fire();
// Output: “Observer 1 is fired!”
// “Observer 2 is fired!”
“`

These are just a few of the many design patterns that can be applied in JavaScript to create efficient and maintainable code. Understanding these patterns and how to implement them can greatly improve the quality and readability of your code.