← Back to courses
Design Patterns
23 Gang of Four patterns · Creational, structural, behavioral · Node.js examples
01Creational Patterns- How objects are created without hard-coding construction everywhere
Singletoncreational
Ensure only one shared instance exists for a resource.
getInstance()
-> exists? return same
-> missing? create once
e.g.: Mongoose connection, Winston logger, config manager
Factory Methodcreational
Create objects through a factory instead of calling constructors directly.
create(type)
email -> EmailNotifier
sms -> SMSNotifier
push -> PushNotifier
e.g.: Express middleware factories, Sequelize dialects
Abstract Factorycreational
Create families of related objects behind one common interface.
DBFactory
-> MySQL connection + query
-> Mongo connection + query
e.g.: TypeORM, Sequelize dialect system, cloud provider SDK wrappers
Buildercreational
Build complex objects step by step with a fluent API.
builder.select()
-> from()
-> where()
-> limit()
-> build()
e.g.: Knex.js, Mongoose query API, request builders
Prototypecreational
Clone an existing object and customize the copy.
base object
-> clone()
-> override fields
-> new variant
e.g.: Object.create(), structuredClone(), config cloning
02Structural Patterns- How objects and modules are composed into larger shapes
Adapterstructural
Translate one interface into another interface your app expects.
Your code expects send(msg)
-> Adapter
-> SDK uses deliver({ body })
e.g.: AWS SDK wrappers, Twilio adapters, payment adapters
Bridgestructural
Separate abstraction from implementation so both can vary independently.
Report
-> Renderer interface
-> PDFRenderer / HTMLRenderer
e.g.: Renderer plugins, storage drivers, notification channels
Compositestructural
Treat single objects and groups of objects the same way.
Folder
-> File
-> Folder
-> File
call size() on any node
e.g.: File trees, React component trees, menu trees
Decoratorstructural
Wrap an object to add behavior without changing the original class.
Base service
-> Auth wrapper
-> Log wrapper
-> Cache wrapper
e.g.: Express middleware, NestJS decorators, service wrappers
Facadestructural
Expose one simple API over a complex subsystem.
placeOrder()
-> reserve inventory
-> charge payment
-> send email
e.g.: Express app.listen(), Mongoose.connect(), SDK clients
Flyweightstructural
Share repeated immutable data to reduce memory usage.
many objects
-> shared intrinsic state
-> per-item external state
e.g.: Object pools, string interning, cached metadata
Proxystructural
Use a stand-in object to control access to the real object.
Client
-> Proxy checks auth/cache/rate
-> Real service
e.g.: JavaScript Proxy, ORM lazy loading, caching proxy
03Behavioral Patterns- How objects communicate, delegate work, and manage behavior
Chain of Responsibilitybehavioral
Pass a request through handlers until one handles it.
Request
-> auth
-> validation
-> controller
-> response
e.g.: Express middleware, Koa middleware, error pipelines
Commandbehavioral
Wrap an action as an object so it can be queued, logged, or undone.
Client creates command
-> queue/log/execute
-> optional undo
e.g.: BullMQ jobs, task queues, undo stacks
Interpreterbehavioral
Represent grammar rules and evaluate expressions.
Input expression
-> parse rules
-> evaluate AST
e.g.: Template engines, rule engines, query parsers
Iteratorbehavioral
Traverse a collection without exposing how it is stored.
Collection
-> iterator.next()
-> item by item
e.g.: for...of, async iterators, streams
Mediatorbehavioral
Centralize communication so objects do not talk directly to each other.
Component A
-> Mediator
-> Component B/C
e.g.: Event bus, message broker wrappers, NestJS CQRS bus
Mementobehavioral
Capture and restore object state without exposing internals.
state now
-> save snapshot
-> changes
-> restore snapshot
e.g.: Undo history, drafts, editor snapshots
Observerbehavioral
Notify subscribed listeners when state changes.
Subject emits event
-> listener A
-> listener B
-> listener C
e.g.: EventEmitter, RxJS, DOM events, Redis pub/sub
Statebehavioral
Change behavior when an object changes internal state.
Order: pending
-> paid
-> shipped
-> delivered
e.g.: Workflow engines, XState, order lifecycles
Strategybehavioral
Swap algorithms at runtime without changing the caller.
Context
-> strategy.pay()
-> Stripe / PayPal / Razorpay
e.g.: Passport strategies, payment strategies, sorting strategies
Template Methodbehavioral
Define an algorithm skeleton and let subclasses fill in steps.
generate()
-> fetch
-> format
-> render
steps vary
e.g.: Report generators, test runners, ETL jobs
Visitorbehavioral
Add operations to object structures without changing those objects.
Visitor
-> visitUser()
-> visitOrder()
-> visitInvoice()
e.g.: AST transforms, Babel plugins, tree walkers
Design patterns are code-structure patterns. They help objects and modules stay flexible, but they should be used when they simplify real change, not just to make code look formal.