Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Patterns for JavaScript, Node.js, and TypeScript

tshemsedinov/Patterns-JavaScript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

30 Commits

Repository files navigation

🧩 Patterns for JavaScript, TypeScript, Node.js

Rethinking GRASP (General Responsibility Assignment Software Patterns), SOLID (Single responsibility, Open–closed, Liskov substitution, Interface segregation, Dependency inversion), GoF (Gang of Four) patterns, for Frontend (browsers) & Backend (node.js, other runtimes) development with JavaScript and TypeScript

Translations: EN, UA, RU.

  • 🧩 Patterns
    • πŸ“’ GoF patterns for Node.js and JavaScript (seminar fragment)
    • 🏭 Creational patterns
      • Abstract factory β€” creates related objects belonging to one family without specifying their concrete classes, e.g., UI components for different platforms.
      • Builder β€” step-by-step assembly of a complex configurable object, often using chaining, e.g., Query Builder or Form Generator.
      • Factory β€” function or method that creates objects using different techniques: assembling from literals and methods, mixins, setPrototypeOf.
      • Factory Method β€” chooses the correct abstraction to create an instance; in JavaScript, this can be implemented using if, switch, or selection from a collection (dictionary).
      • Prototype β€” creates objects by cloning a prepared instance to save resources (not to be confused with Prototype-programming, which is closer to Flyweight).
      • Flyweight β€” saves memory allocation by sharing common state among multiple instances.
      • Singleton β€” provides global access to a single instance; often considered an anti-pattern, easiest implemented via ESM/CJS module caching exported refs.
      • Object Pool β€” reuses pre-created objects to save resources during frequent creation and destruction.
    • 🀝 Structural patterns
      • Adapter β€” converts an incompatible interface into a compatible one, enabling third-party component usage without altering its code; can even transform a function contract into an object or vice versa.
      • Wrapper β€” function wrapper that delegates calls and adds behavior; a specialized case of Adapter.
      • Boxing β€” wraps primitives into object types to add methods or unify interfaces, e.g., narrowing String to AddressString.
      • Decorator β€” dynamically extends behavior without inheritance, typically via composition and declarative syntax, effectively adding metadata.
      • Proxy β€” controls access to an object by intercepting calls, reads, and writes; useful for lazy initialization, caching, and security; can be implemented via GoF or native JavaScript Proxy.
      • Bridge β€” separates two or more abstraction hierarchies via composition or aggregation, allowing them to evolve independently.
      • Composite β€” implements a common interface to uniformly handle individual objects and their tree structures, e.g., DOM or file systems.
      • Facade β€” simplifies access to a complex system, providing a unified and clear interface, hiding and protecting internal complexity.
      • Flyweight β€” saves memory allocation by sharing common state among multiple instances.
    • ⚑ Behavioral patterns
      • Chain of Responsibility β€” passes control through a chain of handlers, selecting a responsible one; all handlers can read, but only one will modify.
      • Middleware β€” handler chain similar to CoR, but each can modify state and pass control to the next one, potentially leading to race conditions and conflicts.
      • Command β€” encapsulates an action (execution request) and parameters into an object, allowing queuing, cancellation, repetition, etc.
      • Interpreter β€” implements a DSL language (Domain Specific Language) or parses expressions into AST (Abstract Syntax Tree) for interpretation.
      • Iterator β€” sequentially traverses collections or streams element-by-element without exposing all data; JavaScript provides built-in Iterator and AsyncIterator.
      • Mediator β€” optimizes communication between N components, centralizing interaction to reduce coupling from N*(N-1)/2 down to N.
      • Memento β€” saves and restores snapshots of an object's state without direct access to its internal state.
      • Observable β€” notifies subscribers about changes to an object's state via Events:
      • State β€” implements a Finite State Machine (FSM) where methods represent transitions, and state is composed into abstraction and switched during transitions.
      • Strategy β€” selects interchangeable behavior at runtime from a collection of implementations: functions, objects, or classes
      • Template method β€” defines algorithm steps, allowing subclasses to override individual steps while defaulting to the superclass behavior.
      • Visitor β€” adds operations to objects without altering their classes, separating structure and behavior into distinct abstractions.
      • Revealing Constructor β€” changes behavior without inheritance, injecting functionality into constructors via functions or objects describing the behavior.
      • Actor – Encapsulates state and behavior, communicating asynchronously via message passing and processing messages in a queue. Ensures thread-safe and async-safe concurrent operations by isolating actor state.
      • Reactor (event-loop) - Handles concurrent events synchronously by adding them to queue and dispatching them to registered handlers. Implements event-driven async processing on the top of the sync one; commonly used in I/O-bound systems.
      • Proactor - Event loop where operations started by user-land code but completed by an external agent (for example I/O subsystem), which then triggers a completion handler when the operation finishes (returning data to callback).
      • Service Locator
    • πŸ—ƒοΈ Data access patterns
      • Transaction Script β€” a procedural pattern where each business operation is implemented as a function or script that coordinates logic, data access, and side effects. Its purpose is to keep logic straightforward and centralized, ideal for simple applications or service-layer orchestration without requiring full domain modeling.
      • Pattern SAGA β€” a distributed transaction pattern where a long-running business process is split into a sequence of local transactions, each with a compensating action in case of failure. It exists to avoid distributed locking.
      • Unit of Work β€” a transactional boundary pattern that tracks changes to business objects and coordinates persistence as a single atomic operation in ORMs or Repository layers to encapsulate all work in a transaction.
      • Table Module β€” a pattern where all domain logic related to a database table is encapsulated in a single class or module, treating rows as simple data.
      • Value Object β€” an immutable, self-validating object that represents a concept in the domain without identity, used to express domain constraints and logic by value rather than reference. It exists to model descriptive attributes, ensure consistency, and support value-based equality in a type-safe, intention-revealing way.
      • Null Object β€” an object that implements a standard interface but provides neutral, do-nothing behavior, designed to avoid null checks, simplify control flow, and ensure polymorphic safety. It exists as a safe default substitute to eliminate conditionals and guard clauses in client code.
      • Active Record β€” domain object encapsulating a database record, providing methods to directly perform CRUD operations (create, read, update, delete) and domain-specific queries on itself.
      • Data access object (DAO) β€” abstraction defining an interface to persist and retrieve domain objects, isolating domain logic from specific storage implementations.
      • Data transfer object (DTO) β€” an anemic object (just plain data) carrier without domain behavior, designed explicitly for transferring structured data across application boundaries, layers, modules, or subsystems.
      • Data Access Layer (DAL) β€” a layer abstracting access to multiple DAOs or raw data sources. Can be represented as Facade pattern. Often includes transformations.
      • Repository β€” domain-centric abstraction for data access that returns domain entities, not raw data or DTOs.
      • Other patterns: Template method, Actor, State, Memento
  • 🧩 GRASP patterns
  • 🧩 SOLID Patterns

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /