Design Principles
Crafting systems that scale with simplicity and sense.
These principles are not slogans. They are lenses that help you make deliberate trade-offs: what to isolate, when to abstract, and how to share intent across a team.
The overview
Each principle is a heuristic. Read it as guidance, not law. The goal is to make better decisions faster—and to explain your reasoning to teammates.
Design Patterns
Learn essential design patterns: creational, structural, and behavioral patterns for building maintainable software.
Creational Patterns
Builder Pattern
Learn the Builder pattern: construct complex objects step by step. Separate construction from representation and create objects with many optional parameters.
Factory Pattern
Learn the Factory pattern: create objects without specifying the exact class. Understand Factory Method and Abstract Factory patterns with examples.
Singleton Pattern
Learn the Singleton pattern: ensure a class has only one instance and provide global access to it. Understand when to use it and common pitfalls.
Structural Patterns
Adapter Pattern
Learn the Adapter pattern: allow incompatible interfaces to work together. Convert interface of a class into another interface clients expect.
Composite Pattern
Learn the Composite pattern: compose objects into tree structures to represent part-whole hierarchies. Treat individual objects and compositions uniformly.
Decorator Pattern
Learn the Decorator pattern: attach additional responsibilities to objects dynamically. Provide a flexible alternative to subclassing for extending functionality.
Proxy Pattern
Learn the Proxy pattern: provide a surrogate or placeholder for another object to control access to it. Understand virtual, protection, and remote proxies.
Behavioral Patterns
Command Pattern
Learn the Command pattern: encapsulate a request as an object, allowing you to parameterize clients with different requests, queue operations, and support undo.
Observer Pattern
Learn the Observer pattern: define a one-to-many dependency between objects. When one object changes state, all dependents are notified automatically.
Strategy Pattern
Learn the Strategy pattern: define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients.
Deep dives
Expand a principle to see a before/after code sketch and a concise takeaway you can bring to code review.
The Open/Closed Principle (OCP) is not about never editing a file. It's about ensuring new behaviour arrives through extension points. A brittle switch statement is a flag that your design stopped listening to OCP.
1// Before: Branching everywhere.2function renderInvoice(type: "standard" | "pro" | "enterprise") {3 if (type === "standard") { /* ... */ }4 if (type === "pro") { /* ... */ }5 if (type === "enterprise") { /* ... */ }6}78// After: Policies are composable.9interface InvoiceRenderer {10 render(): string;11}1213const renderers: Record<string, InvoiceRenderer> = {14 standard: { render: () => /* ... */ "" },15 pro: { render: () => /* ... */ "" },16 enterprise: { render: () => /* ... */ "" },17};1819function renderInvoice(plan: keyof typeof renderers) {20 return renderers[plan].render();21}
Real-world insights
The best design discussions blend architecture and empathy. When a team shares principles, conversations stay anchored in trade-offs, not personal preference. Capture the story behind every principle: how it saved an incident, how it bought you time, how it invited the next engineer in.
Design scales conversations
Shared principles give teams a common language for trade-offs. Use them to align before code is written.
Keep feedback loops short
Pair a principle with instrumentation. If you favour KISS, measure how quickly newcomers ship safe changes.
Bias toward storytelling
Capture case studies of when a principle saved you. Stories make heuristics stick longer than checklists.
"Good design is invisible when it works."
Keep practicing the principles until your future self thanks you for today's clarity.
Explore case studies