Design Patterns
Reusable solutions to common software design problems.
23 lessons
Abstract Factory: Families of Objects
Create families of related objects without specifying their concrete classes — guarantee compatibility between products from the same family.
Adapter: The Interface Translator
Make incompatible interfaces work together — wrap an old or external class behind the interface your system expects without modifying either side.
Bridge: Decoupling Abstraction
Split a large class into two independent hierarchies — abstraction and implementation — so both can evolve without affecting each other.
Builder: Step-by-Step Construction
Construct complex objects step by step — the same construction process can produce different representations using a fluent interface.
Chain of Responsibility
Pass a request along a chain of handlers — each handler decides to process it or pass it to the next, decoupling sender from receiver.
Command: Encapsulating Requests
Transform a request into a standalone object — enabling undo/redo, queuing, logging, and deferred execution of operations.
Composite: Tree Structures
Compose objects into tree structures and treat individual objects and groups uniformly — iterate a file system the same way whether it's a file or a folder.
Decorator: Adding Superpowers
Add behavior to objects dynamically by wrapping them — compose capabilities instead of creating an explosion of subclasses.
Facade: The Friendly Face of the System
Provide a simplified interface to a complex subsystem — hide the chaos behind a single clean entry point without removing the complexity for those who need it.
Factory Method: The Virtual Constructor
Delegate object creation to subclasses — decouple the client from the concrete classes it instantiates.
Flyweight: Sharing to Save Memory
🔒Fit more objects in RAM by sharing common state — separate intrinsic (shared) from extrinsic (unique) data to avoid duplicating heavy objects.
Iterator: Traversing Collections
🔒Traverse elements of any collection without exposing its internal structure — the client never needs to know if it's a list, tree, or graph.
Mediator: Centralized Communication
🔒Restrict direct communication between objects — force them to collaborate through a mediator to reduce chaotic many-to-many dependencies.
Memento: Undo with Snapshots
🔒Capture and restore an object's internal state without violating encapsulation — implement Undo by storing snapshots of past states.
Observer: The Subscription System
🔒Let objects subscribe to events and be notified automatically — decouple event producers from consumers without either knowing about the other.
Prototype: Object Cloning
🔒Copy existing objects without depending on their classes — clone complex configurations instead of rebuilding them from scratch.
Proxy: The Control Intermediary
🔒Provide a substitute that controls access to another object — use for lazy loading, access control, logging, or caching without changing the real object.
Repository Pattern
🔒Abstract data access behind an interface so your business logic never knows whether data comes from a database, cache, or API — and testing becomes a one-liner swap.
Singleton: The Single Instance
🔒Ensure a class has only one instance and provide a global access point — but overuse creates hidden global state and makes testing painful.
State: Behavior Based on State
🔒Allow an object to alter its behavior when its internal state changes — replace state conditionals with polymorphic state objects.
Strategy: Algorithm Swapping
🔒Define a family of algorithms, encapsulate each in its own class, and make them interchangeable at runtime — eliminate conditionals by selecting behavior through composition.
Template Method: Algorithm Skeleton
🔒Define the skeleton of an algorithm in a superclass, but let subclasses override specific steps without changing its structure.
Visitor: New Operations Without Changing Classes
🔒Add new operations to an object hierarchy without modifying the classes — the visitor carries the operation, the elements just accept it.