DEV Community

Cover image for Design Patterns in JavaScript: A Comprehensive Guide

Design Patterns in JavaScript: A Comprehensive Guide

Tope Fasasi on December 25, 2023

JavaScript, with its widespread adoption and versatility, has become a cornerstone of modern web development. As you delve deeper into JavaScript d...
Collapse
 
framemuse profile image
Valery Zinchenko

That's not just JS patterns, it's widely known Gang of Four Patterns.
en.m.wikipedia.org/wiki/Design_Pat...

If you want to know more about Software Design:
en.m.wikipedia.org/wiki/Software_d...
Comprehensive read about System design patterns:
en.m.wikipedia.org/wiki/Category:S...

There is only one downgrade in Wikipedia, the language may be complicated to understand.

Collapse
 
raydot profile image
raydot

I came here to say this exact same thing. These are the typical GoF patterns.

Collapse
 
db325 profile image
db325

Thank you, this found me right in time. I live the way you break down reach pattern and explain the use case asking with the example. This is by far one of the most helpful articles I've read all year!

Collapse
 
jedwards1211 profile image
Andy Edwards • Edited

The singleton example isn’t very idiomatic JS if you ask me…it seems like you were thinking within the conventions of some other language you’re experienced in rather than a natural way of doing things in JS. Two calls to new returning the same object is very very unusual behavior, thus a nasty surprise. JS programmers I know just export a const, or a getter function that returns the same value.

Collapse
 
dev_geos profile image
Dev Geos

I also found this strange but good to know as possibility.

Collapse
 
megathiago profile image
Thiago Marques

The example of Bridge Pattern is not printing the colors as expected.

Collapse
 
pirueto2004 profile image
Julio

I resolved this by invoking the getColor() method for each Color class implementor object:

const redColor = new RedColor().getColor();
const redCircle = new Circle(redColor);
redCircle.draw(); // Output: "Drawing a red circle"

const blueColor = new BlueColor().getColor();
const blueSquare = new Square(blueColor);
blueSquare.draw(); // Output: "Drawing a blue square"

Collapse
 
alex_at_dev profile image
Alex

As already pointed out, these are GoF or general OOP patterns. What I would also like to point out, that -at least for me- this ist not how you would solve the underlying problems in JS / TS, as it's not inherently an OOP language, but a prototype-based language with first-class functions, it's unique way of what you can do with objects and the way the module-system works. For example:

Singleton Pattern
Moules are effectively singletons, so no need to use any other pattern

// module.js
let foo = 'bar';
const singleton = {
  foo,
  logFoo: () => console.log(foo),
}

export const singleton;

// main.js
import {singleton} from './module.js'

singleton.foo = 'baz'; // changed for all uses of "singleton"
singleton.logFoo() // -> 'baz'

// main2.js
import {singleton} from './module.js'
singleton.logFoo() // -> 'baz'

Enter fullscreen mode Exit fullscreen mode

Generally I rarely use classes at all, instead I usually use (typed) objects. My favorite example is the Command pattern.

Command Pattern
This example also uses TypeScript to make sure a command always looks the same. You could also use it with vanilla JS and manually assert command objects always having the same fields. I also added a simple logic to implement undoing commands which in my opinion is one of the biggest real-world strengths / use-cases of this pattern.

type UndoFn<T> = (args: T) => void;

interface Command<T> {
  execute: (args: T) => UndoFn<T>;
}

const logMessageCmd: Command<string> = {
  execute: (msg) => {
    console.log('Message:', msg);
    return () => console.log('Revoked message', msg);
  }
}

const undo = logMessageCmd.execute('Hello World'); // -> 'Message: Hello World'
undo(); // 'Revoked message: Hello World'

Enter fullscreen mode Exit fullscreen mode
Collapse
 
natescode profile image
Nathan Hedglin

Seems like a copy paste from other articles.

"Mediator patterns are a type of behavioral design pattern that define an object that acts as a central hub for coordinating the interactions between a group of objects. The mediator encapsulates the logic and rules for how the objects should communicate, and reduces the coupling between them. The objects only need to know about the mediator, and not about each other. This simplifies the object interfaces and promotes modularity and reusability."

https://www.linkedin.com/advice/how-can-you-coordinate-object-interactions?utm_source=share&utm_medium=member_android&utm_campaign=share_via

Collapse
 
summanerd profile image
Mauricia Ragland • Edited

Great article. I've been doing this for so long that sometimes I forget which patterns I'm using.

The Colleague class in the Mediator example does not look like it will work if colleague2 sends a message.

Your mediator would benefit from a generic send that can determine which objects receive the message:

class Mediator {
    sendMessage(message, sender) {
        for (const colleague of this.colleagues) {
            if (colleague !== sender) {
                colleague.receive(message);
            }
        }
    }
}
class Colleague {
    send(message) {
        this.mediator.sendMessage(message, this);
    }
}
Enter fullscreen mode Exit fullscreen mode

Thanks for this post!

Collapse
 
iamrommel profile image
Rommel C. Manalo • Edited

The title "JS Design Patterns" is misleading, it is not specific to JS. Most programming language that uses OOP can do that. You just write the example in JS.

I think it better to title as Design Patterns with JS examples..

Collapse
 
changwoolab profile image
Changwoo Yoo

I'm not sure but it seems like using ChatGPT to write this article 😂

Collapse
 
bridgerbrowndev profile image
Bridger Brown

Thats a lot of patterns to read, bookmarking lol

Collapse
 
raibtoffoletto profile image
Raí B. Toffoletto

And... you can achieve all of those without using the word CLASS in JS. 😉

Collapse
 
codepraycode profile image
codepraycode

Thank you for this

Collapse
 
james0r profile image
James Auble

Like all too often on dev.to, I think the comments of this article are more helpful and educational than the article itself.

Collapse
 
wakywayne profile image
wakywayne

Why does he not need to call super() in the bridge patter example?

Collapse
 
wakywayne profile image
wakywayne

God tier article

Collapse
 
dev_geos profile image
Dev Geos

I found your post useful even if using of some models is not recommended in JS.
Thanks ! :)

Collapse
 
vanbeonhv profile image
vanbeonhv

I don't think using js class as example for design pattern is a good thing.
after taking a glance at first example. I think I can't get it and apply to my current work