Boundaries are the fundamental unit of design.
Every design decision is a boundary decision. Where you draw the line between modules determines what can change independently, what fails in isolation, and what a reader must hold in their head at once. Coupling, cohesion, encapsulation, and abstraction are all names for the same underlying act: choosing what belongs together and what must stay apart.
Reading path
Coupling and Cohesion
Understanding the fundamental forces that shape software architecture: how modules depend on each other and how well elements within modules work together
- engineering-fundamentals
6 min read
The Purpose of Abstracting
Good abstractions create new semantic levels where you can be absolutely precise, not vague wrappers that leak implementation details.
- engineering-fundamentals
6 min read
Single Responsibility Principle
Why SRP is about having one reason to change, not doing one thing
- engineering-fundamentals
5 min read
DRY and SRP
Resolving the apparent conflict between Don't Repeat Yourself and Single Responsibility Principle in software design
- engineering-fundamentals
4 min read
Dependency Inversion Principle
Why inverting dependencies is the key to flexible, maintainable software architecture
- engineering-fundamentals
7 min read
Interface Segregation Principle
How to design interfaces that are specific to their clients rather than general-purpose, preventing unnecessary dependencies.
- engineering-fundamentals
5 min read
Liskov Substitution Principle
How to ensure your code works with any implementation of an interface or base type, not just the original one.
- engineering-fundamentals
7 min read
SOLID In TypeScript
Practical examples and implementations of SOLID principles using TypeScript, with clear before and after comparisons
- engineering-fundamentals
6 min read
Composition over Inheritance
Why building objects from smaller components creates more flexible and maintainable code than deep inheritance hierarchies
- engineering-fundamentals
2 min read
Law of Demeter
Reduce coupling by limiting object interactions to direct neighbors instead of reaching through multiple objects
- engineering-fundamentals
4 min read
Tell, Don't Ask
Understanding how to maintain proper encapsulation by telling objects what to do rather than asking for their data
- engineering-fundamentals
5 min read
Immutability
Why objects that cannot be changed after creation lead to more predictable, debuggable, and thread-safe code
- engineering-fundamentals
5 min read
Idempotency
Why operations that produce the same result when repeated are essential for reliable distributed systems and fault-tolerant design
- engineering-fundamentals
3 min read
Imperative vs Declarative Paradigms
A practical guide to understanding and effectively using both imperative and declarative programming approaches
- engineering-fundamentals
5 min read
Verbs Over Nouns
How organizing code around behaviors instead of objects creates more maintainable systems and better aligns with business thinking
- engineering-fundamentals
6 min read
Separate Structural Changes from Behavior Changes
Every change is either reshaping the code or changing what it does. Mixing them together is one of the most common sources of unnecessary risk.
- engineering-fundamentals
6 min read