OOP Foundations for Design
The four pillars of object-oriented programming are usually taught as definitions to memorize, which misses what they are for. Each pillar is a decision about change — about which parts of a system are allowed to shift without forcing edits everywhere else. Read this way, each has a purpose (the design problem it solves) that is separate from its mechanism (the language feature that solves it). Mistaking the mechanism for the purpose is the root of most misuse: the feature gets applied where the problem doesn't exist, and you pay for structure you never needed.
SOLID Principles
SOLID is five rules, one per letter, and they share a single aim: to keep a change local. Each rule attacks a specific kind of coupling — the kind that makes one change force many edits — and each has a purpose (the coupling it removes) distinct from its mechanism (how you remove it). Learned as slogans they sound interchangeable; learned as five different answers to the question "what forces an edit here?" they stop blurring together.
Modeling with UML
A design exists in your head as a set of objects and the way they talk to each other. UML is the shared notation for getting that design onto a page precisely enough that someone else — an interviewer, a teammate, or future you — reconstructs the same design you meant. It is easy to over-learn: the full specification has more than a dozen diagram types and a large vocabulary of arrows. Low-level design needs only two of the diagrams and only a handful of the arrows. This note covers that working subset and ignores the rest.
Design Patterns: Orientation
A design pattern is a named, reusable solution to a problem that keeps recurring in object-oriented design. The weight is on named: a pattern is not a library you import or code you paste, but a shape a solution takes, given a name so that two engineers can agree on a design in a single word. Saying "make discounts a Strategy" conveys an entire structure — an interface, interchangeable implementations, a point where one is chosen — that would otherwise take a paragraph to describe. More than anything else, the catalog of patterns is a shared vocabulary.
Creational Patterns
Creational patterns all attack the same coupling: the new ConcreteClass() sitting inside the code that uses the object. That one line ties the caller to a specific class, so changing what gets built means editing the caller. Each pattern below moves creation out of the using code in a different way, so that what is created can change without the code depending on it changing. They range from a plain helper method up to a family-swapping factory; the aim is to pick the lightest one that removes the coupling you actually have.
Structural Patterns
Structural patterns are about composition: how to fit objects together into larger structures while keeping the connections between them loose. Where creational patterns deal with making objects, structural patterns deal with wiring the ones you already have — wrapping one object in another, or arranging many into a whole — so that the arrangement can change without the pieces having to. Each pattern below is a different shape of that wiring.
Behavioral Patterns
Behavioral patterns are about interaction: how objects communicate and how responsibility is divided among them at runtime. Creational patterns make objects and structural patterns arrange them; behavioral patterns govern what happens between them once they exist — who calls whom, who decides what, and how work and messages flow. Each pattern below assigns those responsibilities in a different way.