domain-modeling
Domain Modeling
The model is a claim about the world. Every type says these are the things that exist, every case says these are the ways it can be, every field says this is always known. When the claim is false, the code spends the rest of its life apologising — nullable fields that mean four different things, comments explaining why a state is impossible, validation scattered at every call site because the type would not hold the rule.
Fit the model to the problem, not to the storage, the framework, or the shape of last week's JSON.
Only true statements
Arrange the types so that the invalid statement cannot be spelled. Not checked — unspellable.
Mutually exclusive states are cases of one thing, never a set of booleans and a set of timestamps that could all be set at once. Data known only in one state lives inside that state. A concept with rules gets a type that enforces them at construction, so that possessing one is proof it is valid.
Every null is a question: does this mean not applicable, not yet known, deliberately empty, or nobody has looked? Those are four different facts, and a single null standing for all of them will eventually be read as the wrong one.
The test is not whether the invalid state is prevented. It is whether it can be written down. If it can, someone eventually will.
The words are the model
The names of types, functions, modules, parameters and variables are a story that will be read at three in the morning by someone with no context, quite possibly you.