JavaScript Design Patterns

Concept

Design patterns can be termed as well-documented solutions to the most commonly occurring problems in software engineering. It turns quite hectic for developers to bang out their heads on the problem that someone else has already solved. Every developer aspires to write industrial-level code that is easily applicable to a different problem, be maintainable, and be more readable, and reusable. It needs a proper code structuring mechanism or pattern to be taken into account, and therefore it becomes crucial to solving this challenge. This is where design patterns play an important role by providing ground to these common problems arising in a particular circumstance.

The design patterns are needed because they don't change over time and can be kept into practice with standard or high levels of applications.

In this tutorial, we would be learning these design patterns in JavaScript. Most JavaScript developers frequently interact with design patterns unknowingly while creating applications. This tutorial would cover explanations and examples of the most important and frequently used JavaScript Design Patterns.

Benefits of Design Patterns

They are the best solutions: Design patterns are frequently used by all the developers because they know that it would work. Not only that, they are well aware of the design patterns because they certainly have been revised multiple times before they have been implemented.

They are reusable: Design patterns portray a reusable solution that can be modified under certain circumstances to solve multiple problems, as they cannot exist only to a single problem.

They are expressive: Design patterns need no further explanation because they can explain the large problem to bits and pieces quite efficiently.

They enhance communication: Developers being familiar with design patterns can set common goals to a problem which helps them to communicate with each other about the potential threats and solutions to those problems.

No code refactoring: Design patterns are often termed as optimal solutions for various problems. If an application is being written keeping design patterns in mind, it is assumed that the generated solution is the only efficient solution and hence needs no code refactoring.

They lower codebase size: Being the only optimal solution, design patterns preserve precious space by implementing a required solution in a few lines of code with very little footprint.

Since we have learned much of the basics of the design patterns in JavaScript, let's understand them through coding examples.

Categories

JavaScript Designs Patterns constitute various categories. The given image gives an overview of all the patterns present.

JavaScript Design Patterns

We would now be talking about these three design patterns in detail using suitable examples.

Creational Design Patterns

The above design patterns are all about the instantiation of a class. It can be elaborated further by the division of creating class and object creational patterns. This design pattern deals with the creation of mechanisms that optimize class-object complexities into simple and easy patterns. Complex design patterns need a high approach and time and this problem can be tackled by creational design patterns by controlling the class to inherit effectively and object to use delegation wisely to get the stuff done. Some of the popular design patterns are already shown in the image above. Let's discuss some of the categories.

Constructor Pattern

The construct pattern is simplest, modern, and one of the most popular sub-categories of creational design patterns in JavaScript. The main purpose of this pattern is to felicitate the constructor creation. Consider the below example:

Output

Mercedes gives 20.8 kmpl!

In this example, we have defined a class/function Automobile with attributes brand and mileage. The getDetails() method used in the example will print the given brand and mileage of the automobile in the format shown in the output above. We have instantiated an object for the function/class by provoking the constructor method using new keyword for the given attributes.

Prototype Pattern

Prototyping simply means cloning. Using the prototype patterns, we can instantiate the new object in terms of the template of an existing object with the help of cloning. This is followed by prototypal inheritance to use native prototypical powers of JavaScript. The case can be understood better with the image and coding example shown below.

JavaScript Design Patterns

In this example, we have implemented the use of a prototype cheetah, which is later cloned to create a new object with the Object.create method by creating a constant cheetah1 in which the name of the Trainer will be stored according to the standard ES6 process.

Structural Design Patterns

This design pattern is all about class and object composition or their relationship. It has structurally defined mechanisms for class and objects to ensure that if the part of a system changes, the entire system doesn't rely upon it and change. It is ensured by figuring out the class-creation patterns to use inheritance to compose interfaces and object-creation patterns to define a way to roll out new functionality. It also consists of various categories which are already shown in the image above. Let's discuss some of them.

Adapter Design Pattern

The adaptor design pattern is mainly used for different designs of objects to work together in a single interface. Consider that we are building a library that accepts structures and formats in JSON. We need to have a legacy API to respond in the XML format and this response is later used to generate charts but charts accept only JSON objects. Therefore, an adapter function is written to convert this XML to JSON as and when required. This adapter function would let us connect two different forms of objects. See the below image for reference.

JavaScript Design Patterns

Composite Design Pattern

It is one of the most used structural design patterns where we compose objects into tree structures and then these structural trees are treated as individual objects. Consider a jQuery-based example of how the composite design pattern is structured.

In the above example, jQuery makes it quite easy to apply different methods on the selected DOM nodes by easily accessing combinations. The method addClass is used to hide the details of implementation. It mainly ensures that a group of objects behave as they are individual objects.

Behavioral Design Patterns

This design pattern relies upon the pattern of recognizing, implementing, and communicating between disparate objects. Behavioral patterns are mostly concerned with communication because they help to ensure the disparate parts have proper synchronization of information. Thus, it improves the flexibility of communication.

Let's discuss some categories of a behavioral design pattern.

Chain of Responsibility

This design pattern is mainly used to construct a system where each request passes through a chain of events and is handled by handlers. The requests are processed and passed from one chain to another or are simply rejected. This design pattern is optimal for a system that uses sequential checks for processing requests. Let's take an example of an ATM. Whenever we request a withdrawal amount from ATM, the machine processes the request and dispenses out the amount with a series of combinational notes (Rs.500. Rs. 200, Rs.100).

JavaScript Design Patterns

In this coding example, a request object is created whenever we request an amount to be withdrawn. This provokes a series of calls for the object where it is chained together and event handlers handle particular denominations. Finally, the ATM can dispense the requested combination of notes which satisfies the processed request.

Observer Pattern

The observer pattern is a behavioral design pattern whose main task is to define a subscription mechanism to notify multiple observers or objects about any occurring event. This alerts event handlers to carry out event-driven responses. This pattern is popularly called Pub/Sub that abbreviates for Publication/ Subamount followed by a series of one-to-one dependency amongst objects. This design pattern is used to promote a great object-oriented design and enhance loose coupling.

JavaScript Design Patterns

In this example, we have constructed a notification service system whose task is to notify the user about the subscriptions. In this system, we have created multiple object and event listeners for listening updates which are called subscribers. Therefore, we have defined two classes here namely Subject and Observer. These two classes are needed to hold critical information along with the list of observers. Whenever the critical information state changes, the subject would notify all of its observers about the event using notify method shown in the code above. The observer class invokes an update method that calls notification requests from the subject.

Conclusion

In this tutorial, we learned about various prevailing design patterns in JavaScript and how they tackle common and complex problems with such ease. We also learned about various categories of design patterns mainly creational, structural, and behavioral design patterns. The creational pattern is mainly focused on object-class mechanisms to ease a pattern. The structural design patterns provide a better approach to order a problem and solve them one by one while the behavioral patterns play their role in establishing communication across the activities synchronously. We also explored briefly some of the sub-categories of these three design patterns and how they are accustomed to JavaScript. JavaScript design patterns play a crucial role in building applications. The different categories define different sets of problems existing or might occur whenever we build something. But these patterns ensure that whatever we are building will be best because of the optimal functionality of these design patterns which delivers the best solution for every single design problem occurring in the arena of JavaScript.