Low-Level Design & Design Patterns
SOLID principles, all 23 Gang-of-Four design patterns, and a capstone system-design walkthrough -- learned from real, motivating problems, not memorized definitions.
Practice interview questions on this topic →OOP Recap & UML
beginnerA hands-on refresher on encapsulation, inheritance, abstraction, polymorphism, and composition, plus the UML notation used to diagram class relationships throughout this course.
Single Responsibility Principle
beginnerWhy bundling unrelated jobs onto one class creates hidden coupling, and how splitting a class along its true axes of change keeps each piece independently safe to modify.
Open/Closed Principle
beginnerWhy growing an if/else chain every time a new case appears is a design smell, and how to make a class open to new behavior without ever reopening its already-tested code.
Liskov Substitution Principle
intermediateWhy a subclass that compiles cleanly can still be an unsafe substitute for its parent, and how to design hierarchies where every subtype genuinely honors its parent's contract.
Interface Segregation Principle
intermediateWhy bundling unrelated capabilities into one large interface forces implementers to fake support for things they can't do, and how splitting by capability fixes it.
Dependency Inversion Principle
intermediateWhy hardwiring a high-level class to a low-level implementation makes testing and extension painful, and how depending on a shared abstraction instead makes both sides swappable.
Memento Pattern
intermediateLearn how to add undo functionality to an object without exposing its internal state, by splitting the work across an Originator, an opaque Memento snapshot, and a Caretaker that manages history.
Observer Pattern
intermediateLearn to decouple a data source from everything that reacts to it, by having any number of independent listeners subscribe to a shared notification contract instead of being hardwired in.
Strategy Pattern
intermediateLearn to pull a varying algorithm out of an if/else chain into a family of interchangeable classes, so a new behavior can be added as one new class with zero changes to existing, tested code.
Command Pattern
intermediateLearn to turn a request into a self-contained, queueable object with a standard execute() method, so an invoker like a UI button can trigger any action without knowing what it does.
Template Method Pattern
intermediateLearn to lock a fixed sequence of steps in a base class while letting subclasses fill in exactly one varying step, eliminating duplicated boilerplate across similar classes.
Iterator Pattern
intermediateLearn to expose a uniform way to walk through a collection's elements without leaking its internal storage structure to client code, the same mechanism behind every Java for-each loop.
State Pattern
intermediateLearn how to replace scattered switch statements with self-contained state classes, so an object's behavior changes cleanly as its internal state changes.
Mediator Pattern
intermediateLearn how introducing one central coordinator collapses a tangled web of objects that all reference each other directly into a simple hub-and-spoke design, using a group chat as the running example.
Singleton Pattern
beginnerLearn how to guarantee a class has exactly one instance application-wide, why the naive version breaks under concurrency, and why Singleton has a genuinely bad reputation despite being useful.
Factory Method Pattern
intermediateLearn how to hide the decision of which concrete class to instantiate behind one dedicated method, so callers can request an object by type without ever writing new on a concrete class themselves.
Abstract Factory Pattern
intermediateLearn how to guarantee that a whole family of related objects is created consistently together, using a cross-platform UI kit where a button and a scroll bar must always match the same theme.
Builder Pattern
intermediateLearn how to construct a complex object with many optional parameters step by step and readably, avoiding both a dangerous positional constructor and combinatorial constructor explosion.
Prototype Pattern
intermediateLearn how the Prototype pattern lets an object clone itself instead of forcing client code to rebuild it field by field, and why the shallow-copy versus deep-copy decision is the whole point of the pattern.
Adapter Pattern
intermediateLearn how the Adapter pattern lets an application keep using the interface it already depends on while swapping out the concrete implementation behind it, without touching a single existing call site.
Decorator Pattern
intermediateLearn how the Decorator pattern adds optional, combinable behavior to an individual object at runtime by wrapping it, avoiding the combinatorial subclass explosion that inheritance-based designs run into.
Proxy Pattern
intermediateLearn how the Proxy pattern lets a stand-in object control when an expensive real object actually gets created, enabling lazy loading and caching without the client ever knowing the difference.
Composite Pattern
intermediateLearn how the Composite pattern lets a single leaf object and an entire branch of a tree be treated through one identical interface, so operations like a recursive file-system walk fall out naturally with no type-checking.
Facade Pattern
intermediateLearn how the Facade pattern hides a multi-step coordination sequence across several subsystems behind one simple method, so client code stops needing to know every subsystem exists.
Flyweight Pattern
advancedLearn how to share data across thousands of near-identical objects instead of duplicating it, using a multiplayer shooter's bullets as the running example.
Bridge, Visitor & Chain of Responsibility
advancedThree more classic design patterns, each solving a distinct problem: decoupling two independently varying hierarchies, adding new operations without touching existing classes, and letting a request pass along a chain of handlers until one can process it.
Capstone: Ride-Sharing App
advancedA full interview-style system design walkthrough: build a ride-sharing app the obvious way, find its real bugs and SOLID violations, then refactor it end to end using Strategy, Observer, and Mediator together.