Skip to content

Instantly share code, notes, and snippets.

@iegik
Last active May 8, 2025 17:17
Show Gist options
  • Save iegik/bbfa6f552c7b98cbec031dee12914a0f to your computer and use it in GitHub Desktop.
Save iegik/bbfa6f552c7b98cbec031dee12914a0f to your computer and use it in GitHub Desktop.

Design Patterns in JavaScript

Strategy

Observer

Decorator

Factory

Factory method

Monad

function Maybe(val) {
    this.val = val || null;
}
Maybe.prototype.bind = function (f) {
    return (target => target(this.val))(f);
};
var x = (new Maybe(5));
var y = x
  .bind(v => new Maybe(v + 1))
  .bind(v => new Maybe(v * 2));
// --- Creational Patterns ---
// Singleton Pattern
// Ensures a class has only one instance and provides a global point of access.
interface Singleton {
// The singleton instance might have methods or properties
// operation(): void;
// A static method to get the single instance is typical
getInstance(): Singleton;
}
// Factory Method Pattern
// Defines an interface for creating objects, but lets subclasses alter the type of objects created.
interface Product {
// Common interface for objects created by the factory
use(): void;
}
interface Creator<P extends Product> {
// The factory method - subclasses override this to return specific Product types (P)
// factoryMethod(): P;
// Creator's logic that uses the factory method
// someOperation(): string;
}
// Abstract Factory Pattern
// Provides an interface for creating families of related or dependent objects
// without specifying their concrete classes.
// interface AbstractProductA {
// // Interface for product A
// usefulFunctionA(): string;
// }
// interface AbstractProductB {
// // Interface for product B
// usefulFunctionB(): string;
// // Product B can collaborate with Product A
// anotherUsefulFunctionB(collaborator: AbstractProductA): string;
// }
// interface AbstractFactory {
// // Methods to create a family of products
// createProductA(): AbstractProductA;
// createProductB(): AbstractProductB;
// }
// Constructor Pattern
// A fundamental pattern using functions/classes to initialize objects.
// interface Person {
// name: string;
// age: number;
// greet(): void;
// }
// Prototype Pattern
// Creates new objects by cloning an existing object (the prototype).
interface Prototype {
// Method to clone the object
clone(): Prototype;
}
// Builder Pattern
// Separates the construction of a complex object from its representation.
interface Builder<T extends string | string[] = string[], P extends ProductForBuilder = ProductForBuilder> {
// Use a mapped type to define build methods based on the keys of T (if T is a string union)
// or allow any string key if T is string[] or a general string.
// This creates methods like buildPartA, buildPartB, etc.
[K in T extends string ? `build${K}` : T extends string[] ? `build${T[number]}` : string]: () => void;
// Method to get the final built object
getProduct(): P;
// Optional: Method to reset the builder for a new construction
reset?(): void;
}
interface ProductForBuilder {
// The complex object being built
parts: string[];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment