Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Node.js  Design Patterns

You're reading from   Node.js Design Patterns Master best practices to build modular and scalable server-side web applications

Arrow left icon
Product type Paperback
Published in Jul 2016
Publisher Packt
ISBN-13 9781785885587
Length 526 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Authors (3):
Arrow left icon
Luciano Mammino Luciano Mammino
Author Profile Icon Luciano Mammino
Luciano Mammino
Mario Casciaro Mario Casciaro
Author Profile Icon Mario Casciaro
Mario Casciaro
Joel Purra Joel Purra
Author Profile Icon Joel Purra
Joel Purra
Arrow right icon
View More author details
Toc

Table of Contents (12) Chapters Close

Preface 1. Welcome to the Node.js Platform 2. Node.js Essential Patterns FREE CHAPTER 3. Asynchronous Control Flow Patterns with Callbacks 4. Asynchronous Control Flow Patterns with ES2015 and Beyond 5. Coding with Streams 6. Design Patterns 7. Wiring Modules 8. Universal JavaScript for Web Applications 9. Advanced Asynchronous Recipes 10. Scalability and Architectural Patterns 11. Messaging and Integration Patterns

The Node.js philosophy

Every platform has its own philosophy—a set of principles and guidelines that are generally accepted by the community, an ideology of doing things that influences the evolution of a platform, and how applications are developed and designed. Some of these principles arise from the technology itself, some of them are enabled by its ecosystem, some are just trends in the community, and others are evolutions of different ideologies. In Node.js, some of these principles come directly from its creator, Ryan Dahl; from all the people who contributed to the core; from charismatic figures in the community; and some of the principles are inherited from the JavaScript culture or are influenced by the Unix philosophy.

None of these rules are imposed and they should always be applied with common sense; however, they can prove to be tremendously useful when we are looking for a source of inspiration while designing our programs.

Note

You can find an extensive list of software development philosophies on Wikipedia at http://en.wikipedia.org/wiki/List_of_software_development_philosophies.

Small core

The Node.js core itself has its foundations built on a few principles; one of these is having the smallest set of functionalities, leaving the rest to the so-called userland (or userspace), the ecosystem of modules living outside the core. This principle has an enormous impact on the Node.js culture, as it gives freedom to the community to experiment and iterate quickly on a broader set of solutions within the scope of the userland modules, instead of being imposed with one slowly evolving solution that is built into the more tightly controlled and stable core. Keeping the core set of functionalities to the bare minimum, then, not only becomes convenient in terms of maintainability, but also in terms of the positive cultural impact that it brings on the evolution of the entire ecosystem.

Small modules

Node.js uses the concept of a module as a fundamental means to structure the code of a program. It is the building block for creating applications and reusable libraries called packages (a package is also frequently referred to as a module since, usually, it has one single module as an entry point). In Node.js, one of the most evangelized principles is to design small modules, not only in terms of code size, but most importantly in terms of scope.

This principle has its roots in the Unix philosophy, particularly in two of its precepts, which are as follows:

  • "Small is beautiful."
  • "Make each program do one thing well."

Node.js brought these concepts to a whole new level. Along with the help of npm, the official package manager, Node.js helps solve the dependency hell problem by making sure that each installed package will have its own separate set of dependencies, thus enabling a program to depend on a lot of packages without incurring conflicts. The Node way, in fact, involves extreme levels of reusability, whereby applications are composed of a high number of small, well-focused dependencies. While this can be considered unpractical or even totally unfeasible in other platforms, in Node.js this practice is encouraged. As a consequence, it is not rare to find npm packages containing less than 100 lines of code or exposing only one single function.

Besides the clear advantage in terms of reusability, a small module is also considered to be the following:

  • Easier to understand and use
  • Simpler to test and maintain
  • Perfect to share with the browser

Having smaller and more focused modules empowers everyone to share or reuse even the smallest piece of code; it's the Don't Repeat Yourself (DRY) principle applied to a whole new level.

Small surface area

In addition to being small in size and scope, Node.js modules usually also have the characteristic of exposing a minimal set of functionalities. The main advantage here is increased usability of the API, which means that the API becomes clearer to use and is less exposed to erroneous usage. Most of the time, in fact, the user of a component is only interested in a very limited and focused set of features, without the need to extend its functionality or tap into more advanced aspects.

In Node.js, a very common pattern for defining modules is to expose only one piece of functionality, such as a function or a constructor, while letting more advanced aspects or secondary features become properties of the exported function or constructor. This helps the user to identify what is important and what is secondary. It is not rare to find modules that expose only one function and nothing else, for the simple fact that it provides a single, unmistakably clear entry point.

Another characteristic of many Node.js modules is the fact that they are created to be used rather than extended. Locking down the internals of a module by forbidding any possibility of an extension might sound inflexible, but it actually has the advantage of reducing the use cases, simplifying its implementation, facilitating its maintenance, and increasing its usability.

Simplicity and pragmatism

Have you ever heard of the Keep It Simple, Stupid (KISS) principle or the famous quote:

 

"Simplicity is the ultimate sophistication."

 
 --Leonardo da Vinci

Richard P. Gabriel, a prominent computer scientist, coined the term "worse is better" to describe the model, whereby less and simpler functionality is a good design choice for software. In his essay, The Rise of "Worse is Better", he says:

"The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design."

Designing simple, as opposed to perfect, fully-featured software, is a good practice for several reasons: it takes less effort to implement, allows faster shipping with fewer resources, is easier to adapt, and is easier to maintain and understand. These factors foster community contributions and allow the software itself to grow and improve.

In Node.js, this principle is also enabled by JavaScript, which is a very pragmatic language. It's not rare, in fact, to see simple functions, closures, and object literals replacing complex class hierarchies. Pure object-oriented designs often try to replicate the real world using the mathematical terms of a computer system without considering the imperfection and the complexity of the real world itself. The truth is that; our software is always an approximation of reality, and we would probably have more success in trying to get something working sooner and with reasonable complexity, instead of trying to create near-perfect software with huge effort and tons of code to maintain.

Throughout this book, we will see this principle in action many times. For example, a considerable number of traditional design patterns, such as singleton or decorator, can have a trivial, even if sometimes not foolproof, implementation and we will see how an uncomplicated, practical approach (most of the time) is preferred to a pure, flawless design.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime