Domain Modeling
Entities, value objects, aggregates and services — plus the honest question of whether a rich domain model earns its cost over a transaction script for the system in front of you.
Getting the nouns and verbs the business actually uses into the code, so a requirement in their sentence maps to a change in one of yours.
One word for one concept, in conversation and in code — where the concept is real. The failure is three names for one thing across three modules, all of them defensible.
Some things are the same thing after every one of their fields has changed. Order #123 is still order #123 — identity, not equality, is what defines them.
Things defined entirely by their value — Money, EmailAddress, Coordinates. The highest-value, lowest-cost idea in this module, and the one worth adopting even if you take nothing else.
A consistency boundary drawn around state that must change together. Powerful and easy to over-apply — most objects are not aggregates and should not be treated as one.
One door into the boundary. External changes go through the root so the invariant has exactly one place it can be checked — and exactly one place it can be bypassed.
For the operations that genuinely belong to no single entity or value object. A small, useful category — and a dumping ground the moment it stops being small.
Data objects with no behaviour, and all the logic in services. Widely called an anti-pattern, widely defended, and correct more often than either side admits.
One procedure per operation, top to bottom, doing the whole job. Often exactly right — and the criteria for when it stops being right are knowable in advance.
The machinery costs vocabulary, indirection and mapping on every change. It repays only at real domain complexity, with real access to someone who knows the domain.