principle-model-the-domain
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseModel the Domain
领域建模
Encode the real domain in a data structure instead of scattering it across conditionals.
Why: Scattered booleans, repeated shape assumptions, and branching spread across files are accidental complexity. A structure that matches the domain makes invalid states unrepresentable and deletes branches. Choosing it at write time is cheap; recovering it later reads as a refactor and gets deferred.
Reach for structures like these:
- A state machine instead of scattered booleans, phases, or lifecycle checks.
- A typed object/model instead of loose parameters or repeated shape assumptions.
- A map, registry, lookup table, or discriminated union instead of branching spread across files.
- A reducer or command/event model instead of ad hoc state mutations.
- A module organized around one body of domain knowledge instead of a sequence such as load, validate, transform, and save. Execution order is not ownership.
- A small module boundary that gathers repeated behavior, ownership, or invariants.
- A queue, cache, index, graph/tree, or normalized collection where the data access pattern calls for it.
- Any other structure that fits. The list above covers the common cases only. When none fits, work out what the code must never allow and how the data gets read, then find the structure that encodes exactly that.
Do not force an abstraction. Prefer boring code if the current shape is already clear, local, and unlikely to grow. Be skeptical of an abstraction that adds indirection without removing branches, duplicated rules, invalid states, or lifecycle risk.
The tell that you skipped this is a new feature that grows an existing if/else chain by one more branch, or a second boolean that must stay in sync with the first. Temporal decomposition is another tell. Phase-named modules repeat the same domain rules across steps.
将真实领域逻辑编码为数据结构,而非分散在各处的条件判断中。
原因: 分散的布尔值、重复的形状假设以及跨文件的分支判断属于偶发复杂度。与领域匹配的结构化设计可避免无效状态的出现,并消除分支判断。在编写代码时采用这种设计成本很低;而后续再重构实现则会被推迟。
可选用以下这类结构:
- 用 state machine 替代分散的布尔值、阶段或生命周期检查。
- 用类型化对象/模型替代松散参数或重复的形状假设。
- 用映射表、注册表、查找表或 discriminated union 替代跨文件的分支判断。
- 用 reducer 或命令/事件模型替代临时状态变更。
- 围绕某一领域知识组织模块,而非按加载、验证、转换、保存等执行顺序划分。执行顺序并不等同于代码所有权。
- 用较小的模块边界整合重复的行为、所有权或不变量。
- 在数据访问模式需要时,使用队列、缓存、索引、图/树或规范化集合。
- 任何其他适用的结构。上述列表仅涵盖常见场景。若没有合适的结构,先明确代码必须禁止的情况以及数据的读取方式,再找到能精准实现该要求的结构。
不要强行抽象。如果当前代码结构已经清晰、局部化且不太可能扩展,宁愿选择简单直接的代码。对于那些未消除分支、重复规则、无效状态或生命周期风险,却增加了间接性的抽象,要保持怀疑态度。
判断你是否忽略了这一原则的迹象包括:新增功能时在现有 if/else 链中多添加一个分支,或者新增一个必须与第一个布尔值保持同步的第二个布尔值。时间分解是另一个迹象:按阶段命名的模块会在各个步骤中重复相同的领域规则。