JavaScript Design Patterns
Last Updated :
28 May, 2024
JavaScript design patterns are reusable solutions to common software design problems encountered in JavaScript development. They help in structuring code, promoting modularity, improving maintainability, and ensuring best practices for scalable and efficient applications.
Many developers have documented their solutions to these problems over time, and as more and more people began to use them, they became widely accepted as a standard way of problem-solving. This led to the term “design patterns” being coined to describe them.
As the importance of design patterns became better understood, they were further developed and standardized. Today, most modern design patterns have a defined structure and are organized into multiple categories. They are also commonly taught as independent topics in computer science-related degrees.
In this JavaScript Design Patterns article, You’ll learn various types of Design Patterns like creational patterns, structural patterns, and behavioral patterns along with coding examples provided by JavaScript.
JavaScript Design Patterns
- JavaScript design patterns are the reusable solutions that are applied to commonly occurring issues/problems in writing JavaScript web applications.
- They help us to make our code more robust (strong).
- These patterns help to write organized, beautiful and well-structured codes.
- These design patterns decrease the overall codebase by segregating away all the unnecessary repetitions.
Classification of JavaScript Design Patterns
- The 23 Gang of Four (commonly known as GoF) is generally considered as the foundation of all other pre-existing patterns.
- So JavaScript Design Patterns in context to that are generally classified in three different categories: Creational Design Pattern, Structural Design Pattern, Behavioral Design Pattern.
Now let us study each one of these three methods in a very manner, i.e. by covering some of the major points briefly.
1. JavaScript Creational Design Pattern
These patterns deal with the object-creation mechanism. They try to create objects in a manner that is suitable for a particular situation.
Following is the list of some of the JavaScript Creational Design Patterns, along with their brief description-
- Abstract Factory Design Pattern: This pattern actually creates an object that creates objects over a commonly mentioned or existing theme. This actually means that this method allows us to return a factor containing a group of related classes or objects.
- Builder Design Pattern: This design pattern allows us to create complex objects by specifying the type and the content only. Things that are involved in the constructor are made hidden from the client.
- Factory Method Pattern: This design pattern creates an abstract object or a class but lets the other subclasses or objects decide which method or object or method to instantiate (that is used to make an instance of that class or method).
- Prototype Design Pattern: This design method helps us to create new objects but rather than returning a new object which is non-initialized, it actually returns a new object with values that are copied from the prototype (for example- an object, or a class)
- Singleton Design Pattern: This design pattern allows any user to limit the number of instances of any particular object to just one and this single instance is referred to as a singleton.
2. JavaScript Structural Design Pattern
This design pattern allows us to know how the classes and the objects created so far can be compared to form larger structures. This design pattern eases the design by identifying a simple way to realize relationships among entities.
Following is the list of some of the JavaScript Structural Design Patterns, along with their brief description-
- Adapter Design Pattern: This design pattern helps us in the translation of one interface (that is, an object’s properties and methods) to another and that is why this design pattern is also referred to as the Wrapper Pattern.
- Bridge Design Pattern: This design pattern allows to have multiple components in existence having their individual interfaces (that is, their own individual properties or methods). This is a very high-level architectural pattern.
- Composite Design Pattern: This design pattern allows us to create object properties that are primitives items (items that are old or in existence previously) or a collection of objects.
- Flyweight Design Pattern: This design pattern actually helps us in conserving memory by sharing a large number of objects efficiently these shared objects actually immutable.
- Proxy Design Pattern: This design pattern allows us to create a separate or a placeholder object for another object which will further be able to control this mentioned object.
3. JavaScript Behavioral Design Pattern
This design pattern identifies common communication patterns among objects. This actually increases flexibility in carrying out the communication.
Following is the list of some of the JavaScript Behavioral Design Patterns, along with their brief description-
- Chain of Responsibility Design Pattern: This pattern provides us the chain of loosely coupled objects and from those objects, one will actually help us to provide the provide. Hereunder this method, things will work as in linear search mode or manner.
- Command Design Pattern: This pattern actually encapsulates various actions as objects, which thus allows systems to separate the objects that issue a request from the objects that actually process the object.
- Interpreter Design Pattern: This design pattern offers us a scripting language for end-to-end users to customize their solutions.
- Observer Design Pattern: This design pattern offers a model in which objects subscribe to an event and gets notified when any of the events occur. This pattern promotes good object-oriented design and loose coupling.
- State Design Pattern: This design pattern provides state-specific logic actually to a limited set of objects in which each object represents a particular state.
Now after understanding each of the above-illustrated design patterns in a brief efficient manner let us move forward and see some of the coding examples which will help us to understand some of the above-mentioned design patterns of various different categories-
Benefits of JavaScript design patterns
- Proven and reliable: Their widespread use by developers confirms their effectiveness and ensures they’ve been thoroughly tested and improved.
- Versatile and adaptable: They represent general solutions that can be tailored to address various specific problems, making them highly reusable.
- Concise and clear: Design patterns express complex solutions in an elegant and understandable way.
- Boost communication: Shared knowledge of design patterns facilitates communication among developers by providing a common language for discussing potential solutions.
- Refactoring-friendly: Designing applications with design patterns in mind often reduces the need for future code refactoring as they represent optimized solutions.
- Compact and efficient: Design patterns typically require less code compared to other solutions due to their optimized and elegant nature.
Examples of JavaScript Design Patterns
Example 1: In this example, we will see how the Builder design pattern, as well as the Chain of Responsibilities design pattern, works.
Javascript
let Task = function (name, description) {
this.name = name;
this.description = description;
};
let TaskBuilder = function () {
let name;
let description;
this.setName = function (name) {
this.name = name;
return this;
};
this.setDescription = function (description) {
this.description = description;
return this;
};
this.build = function () {
return new Task(this.name, this.description);
};
return this;
};
let task = new TaskBuilder();
let object = task
.setName("First Task")
.setDescription("Study React and TypeScript")
.build();
console.log(object);
Output:
Task { name: 'First Task', description: 'Study React and TypeScript' }
Example 2: In this example, we will understand how does Proxy Design Pattern works. Here we will create a proxy method that actually works for the main method since it is responsible for all the output which user wants to display as a result.
Javascript
function mainDisplayFunction() {
this.getData = function (name) {
if (name === "ABC") return 20000;
else if (name === "DEF") return 5000;
else return 0;
};
}
function proxyDisplayFunction() {
let object_1 = new mainDisplayFunction();
let result_object = {};
return {
getData: function (name) {
if (!result_object[name]) {
result_object[name] = object_1.getData(name);
}
console.log(name + ": " + result_object[name]);
return result_object[name];
},
};
}
function mainFunction() {
let main_object = new proxyDisplayFunction();
main_object.getData("ABC");
main_object.getData("DEF");
main_object.getData("Apple");
}
mainFunction();
Output:
ABC: 20000
DEF: 5000
Apple: 0
Please Login to comment...