Design patterns in JavaScript

Introduction to JavaScript design patterns

Have you ever looked at your code and though … Man, this is a real mess! Well, this happened yesterday when I was looking at the JavaScript code of my website. I started to think about how to improve not just my coding skills, but the way the code is designed. After a few minutes of searching, I came across an interesting subject called design patterns. Although nothing is perfect, it seems that design patterns can make it easier to adopt a better approach to building web applications and coding in general. Let’s take a look.

What are design patterns?

Let’s start with the basics. What is a pattern? In software design, pattern is any solution you can apply again and again to problems you face repeatedly. The crucial factor that makes these solutions patterns is that they are reusable. From a web design perspective, you can also imagine patterns as some sort of templates you can use to solve problems. Keep in mind that patterns are not an exact A, B, C plan to follow. Their role, not just in JavaScript, is to provide you with a scheme, not to solve every design problem you might encounter.

Advantages of using design patterns in JavaScript

Design patterns are proven and time-tested solutions. By using a design patterns, you will follow a solid approach that was tested and proven by many professionals in the industry. All the patterns you will work with include specific techniques that reflect the experience, insights and also the knowledge of the developers that helped create them.

Design patterns can be easily reused. Let’s be honest … Who wants to reinvent the wheel every time when starting a new project? Why should you start on greenfield or blank canvas? It is a waste of your time. Instead, you can choose smarter way and use something created earlier, such as design patterns. Patterns are, in general, an out of the box solution that you can modify or enhance to suit your own needs and make them more robust.

Design patterns can make your code cleaner. One thing design patterns carry is expressiveness. Meaning, when you look at a pattern, usually you will find a specific structure and vocabulary set in place. This will help present the solution, no matter how comprehensive it is, in quite an elegant way and make the solution easier to understand.

Also, by reusing patterns you can prevent minor issues from happening and avoid some bigger problems in the future. When you create write the code using tested design patterns, you don’t have to spend time thinking about its structure. It is already prepared. This means you can narrow your focus on other aspects of the project, such as the quality. What’s more since design patterns are well organized you will not need to refactor the code in the future.

Want to save some bandwidth and speedup the loading time? Some, not all, design patterns can help you decrease the amount of our code and overall size of files by avoiding repetition. By going through the code and looking at it more closely, you can find spots where you can reduce repetition of similar tasks. Then, you can replace those repetitive tasks with one reusable function. This practice is known as making code DRY.

The last advantage or benefit of using design patterns is close related to the fundamental principle of open source. Patterns that are used frequently by higher number of developers can be improved over time. This will happen through contribution and implementation of experiences of other developers using those patterns. It is not so rare that this can lead to birth of new design patterns. Also, contribution of other developers will make the pattern more robust and easier to work with, not to mention more universal.

Categories of JavaScript design patterns

In software development, you can find many categories of design patterns. In this post, we will focus on three of them along with which patterns belong where. These categories are creational, structural and behavioral.

Creational patterns

Let’s start with creational patterns. Design patterns in this category focus on ways to create objects or classes in the best way suitable for the situation we’re working in. Otherwise, commonly used approach to object creation might result in higher complexity, which is something we are trying to avoid. Creational design patterns solve this problem by going into the fundamentals of the code and controlling the process of creation itself.

Some patterns you will find under creational patterns category are:

abstract–this one creates an instance of several families of classes without detailing concrete classes and does not use the new operator;

builderBuilder separates the construction of a complex object from its representation, so the same construction process can create different representations.

factory–Factory method makes an instance of several classes based on interfaced data or events, but let subclasses decide which to instantiate. Also does not use the new operator.

prototypeCreates a fully initialized instances using a prototypical instance and creates new objects by copying this prototype.

singleton–Every class has only one instance with global access points to it.

Structural patterns

Structural patterns are focused on managing the relationships between different object and their composition. The overall goal is to be able to make your solution scalable. One of the key principles of structural patterns is to ensure that a change in one part of your solution will not influence another one. In other words, the entire system is composed of independent self-sufficient blocks of code.

Some of the structural patterns are:

adapter–Adapter will let the classes work together in incompatible interfaces by converting the interface of a class into another interface.

decoratorDecorator dynamically attach additional responsibilities and processing to an object and extend its functionality.

facadeFacade creates a unified, or a high-level, interface to a set of interfaces in a subsystem and makes these subsystems easier to use. Meaning, complicated subsystem wrapped in a simpler interface.

flyweightFlyweight is an instance using sharing of information to support large numbers of fine-grained objects efficiently.

proxyProxy provides a place holder for another object to control access to it.

Behavioral patterns

The last category of design patterns are behavioral patterns. Since every object-oriented systems contain some objects, there will also exist a communication between those objects. Behavioral design patterns goal is to define different methods to organizing this communication and make it as smooth and easy as possible.

Some examples of behavioral patters are:

iterator–Iterator sequentially access the elements of a collection without showing the underlying representation.

mediator–Mediator define an object that encapsulates how a set of objects interact with each other and keep these objects from referring to each other explicitly.

observer–Observer defines a one-to-many dependency between various objects so that when one object changes state, all its dependents are notified and updated automatically.

visitorVisitor will let you define a new operation without actually changing the classes of the elements.

Tips for creating new JavaScript design patterns

Do you want to create your own design patterns for your JavaScript projects? First, remember that writing really good patterns is a challenge. It is not something that you can do in fifty-fifty style. If you want to make your own JavaScript design pattern, you have to keep few things in mind. You need to provide the pattern with proper reference material for end-users, so they can understand and use it. Also, make it easy for user to defend why using your pattern is necessary for their project. What should you consider?

First, ask yourself … How practical is the pattern? Ensure that every pattern describes proven solutions to recurring problems instead than just some speculative solutions which you have no experience with–hypothetical problem.

Second, keep best practices in mind. Every design decisions you make or made should be based on principles you learned from best practices. Following the best practices will also make it easier to understand the code, avoid issues and maintain it in the future.

Third, always make sure your design patterns are transparent and easy to grasp for the user. Design patterns you create should be transparent to any type of user-experience. Remember, that these patterns are here primarily to serve the developers using them and help them get the job done. They should not force any changes to user’s behavior that would not ocurred if the developer would not use the pattern.

Fourth, remember that originality is not key in pattern design. When writing a pattern, you dont need to be the original, at least not always. Even though being a discoverer of the solutions might sound pretty good, you should switch your focus on the design. Otherwise, it can start to overlap with minor pieces of other design patterns. So, make sure the approach you created is strong enough and can be applied to variety of problems and it will have a chance of being recognized as a valid pattern.

Fifth, pattern need a strong set of examples. What is the best and fastest way to learn something? Learning from examples. The same thing applies to design patterns as well. Make sure to write a good description of your pattern followed by solid amount of quality code examples to demonstrate the use of the pattern. The best examples are the ones that applies their principles to wide range of problems.

Final words

Design patterns are not perfect and have to face some criticism as any other approach. Some of those arguments are that they might target the wrong problem, lack any formal foundation, lead to inefficient solutions and so on. In case of design patterns, as with any other tool, the only thing that matters is what is your opinion about it and whether you decide to use it or not. So, collect the data, read the good, the bad and decide for yourself.

If you liked this article, please subscribe so you don't miss any future post.

If you'd like to support me and this blog, you can become a patron, or you can buy me a coffee 🙂

By Alex Devero

I'm Founder/CEO of DEVERO Corporation. Entrepreneur, designer, developer. My mission and MTP is to accelerate the development of humankind through technology.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.