specsfy-specialist-domain-modeling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Modelagem de domínio

领域建模

Quando usar

使用场景

  • Acionar quando um termo do domínio for ambíguo, dois contextos usarem a mesma palavra com sentidos diferentes, ou uma regra/invariante não tiver owner claro.
  • Acionar também antes de desenhar uma entidade nova quando não estiver claro se ela é entidade, value object, evento ou apenas uma projeção.
  • Não acionar para decidir topologia de serviços, banco ou infraestrutura — isso é
    $specsfy-specialist-software-architecture
    ; a modelagem de domínio informa essa decisão, não a substitui.
  • Combinar com
    $specsfy-specialist-software-architecture
    quando um bounded context novo implicar um boundary de serviço ou de dados novo.
  • 当领域术语存在歧义、两个上下文对同一词汇的理解不同,或者规则/Invariant没有明确负责人时触发。
  • 当不清楚新创建的对象是Entity、Value Object、Event还是仅为Projection时,在设计新实体前触发。
  • 不要用于决定服务拓扑、数据库或基础设施——此类情况属于
    $specsfy-specialist-software-architecture
    的范畴;领域建模为这些决策提供依据,但不替代它们。
  • 当新的Bounded Context意味着需要新的服务或数据边界时,结合
    $specsfy-specialist-software-architecture
    使用。

Fluxo

流程

  1. Identificar atores, seus objetivos, os comandos que emitem, os fatos que já ocorreram (eventos) e as regras que restringem transições.
  2. Coletar os termos reais usados pelas pessoas do domínio — não os nomes de tabela ou classe já existentes — e expor sinônimos e colisões de sentido.
  3. Construir cenários concretos: caminho feliz, limite, falha e efeito do tempo (o que muda se o comando chegar tarde, duplicado ou fora de ordem).
  4. Formular cada invariante como uma afirmação sempre verdadeira e atribuir o owner (o componente/agregado capaz de garanti-la no momento da escrita).
  5. Agrupar comportamento pelo que precisa mudar junto e ser consistente imediatamente — isso define o limite do aggregate, não a conveniência de consulta.
  6. Testar cada boundary proposto contra um caso que o atravessa: um dado correto no meio já quebra a fronteira, o boundary está no lugar errado.
  7. Atualizar glossário, mapa de contexto e ADR na fonte autorizada do projeto — nunca criar um documento de modelo paralelo.
  1. 识别参与者、他们的目标、发出的命令、已发生的事实(Event)以及限制状态转换的规则。
  2. 收集领域人员实际使用的术语——而非现有数据库表或类的名称——并梳理同义词和语义冲突。
  3. 构建具体场景:正常流程、边界情况、失败场景以及时间影响(命令延迟、重复或乱序到达时会发生什么变化)。
  4. 将每个Invariant表述为始终成立的断言,并指定负责人(能够在写入时保证该Invariant的组件/Aggregate)。
  5. 按照“需要一起变更且需立即保持一致性”的原则对行为进行分组——这定义了Aggregate的边界,而非出于查询便利性。
  6. 用跨边界的案例测试每个提议的边界:如果中间的正确数据会打破边界,则说明边界位置错误。
  7. 更新项目权威来源中的术语表、上下文映射和ADR(架构决策记录)——切勿创建并行的模型文档。

Padrões

模式

  • Nomear pelo vocabulário do domínio (linguagem ubíqua), nunca pela camada técnica ("Gerenciador", "Handler", "Processor" sozinhos não são domínio).
  • Distinguir entidade (identidade + ciclo de vida), value object (definido pelo valor, imutável), evento (fato já ocorrido, nome no passado) e projeção (leitura derivada, não fonte de verdade) pelo comportamento que cada um exige, não pela conveniência de implementação.
  • Manter cada invariante junto do componente capaz de garanti-la atomicamente — invariante que depende de dois agregados sem coordenação é invariante quebrada sob concorrência.
  • Não agrandar um aggregate para facilitar uma consulta; consultas compostas usam projeção/read model, não um aggregate maior que o necessário para consistência.
  • Separar bounded contexts quando o mesmo termo tem modelos legítimos e incompatíveis (ex.: "Cliente" no contexto de Vendas vs. "Cliente" no contexto de Suporte podem ter atributos e ciclo de vida diferentes).
  • Nomear eventos no passado ("PedidoConfirmado") e comandos no imperativo ("ConfirmarPedido") — a diferença de tempo verbal comunica se algo já aconteceu ou está sendo solicitado.
  • Validar cada definição com um exemplo que a satisfaz e um contraexemplo que a quebraria — uma definição sem contraexemplo geralmente é vaga demais para implementar.
  • 使用领域词汇(Ubiquitous Language)命名,切勿仅使用技术层名称(单独的“Gerenciador”“Handler”“Processor”不属于领域术语)。
  • 根据每种类型所需的行为,区分Entity(具有标识+生命周期)、Value Object(由值定义、不可变)、Event(已发生的事实,使用过去式命名)和Projection(衍生的查询模型,不是事实来源),而非出于实现便利性。
  • 将每个Invariant与能够原子性保证它的组件放在一起——依赖两个未协调的Aggregate的Invariant,在并发场景下会被破坏。
  • 不要为了方便查询而扩大Aggregate的范围;复合查询应使用Projection/Read Model,而非超出一致性需求的更大Aggregate。
  • 当同一术语在不同场景下有合法且不兼容的模型时,拆分Bounded Context(例如:“Cliente”在销售上下文与支持上下文中的属性和生命周期可能不同)。
  • Event使用过去式命名(如“PedidoConfirmado”),命令使用祈使句命名(如“ConfirmarPedido”)——时态差异用于区分事件已发生还是正在被请求。
  • 用一个符合定义的示例和一个违反定义的反例来验证每个定义——没有反例的定义通常过于模糊,无法实现。

Antipadrões

反模式

  • Anemic domain model: entidades que são só sacos de campos (getters/ setters) enquanto toda a regra vive em serviços externos — perde a garantia de invariante no ponto de mutação e espalha a regra por múltiplos callers que podem esquecê-la.
  • Usar o mesmo nome de campo/classe em dois bounded contexts assumindo que significam a mesma coisa — força um dos dois a distorcer seu modelo para caber no vocabulário do outro.
  • Aggregate que cobre o "gráfico de objetos inteiro" para nunca ter que unir dados depois — cria contenção de escrita e trava concorrência que nada no domínio exige.
  • Documentar o modelo em um arquivo à parte da fonte autorizada (spec, código) — o documento diverge do sistema real na primeira mudança não sincronizada.
  • Anemic Domain Model:实体仅作为字段容器(只有getter/setter),所有规则都存在于外部服务中——在变更点失去对Invariant的保证,且规则分散在多个调用方中,容易被遗漏。
  • 在两个Bounded Context中使用相同的字段/类名,并假设它们的含义相同——迫使其中一个上下文扭曲自身模型以适配另一个的词汇。
  • Aggregate覆盖“整个对象图”以避免后续数据拼接——造成不必要的写入竞争和并发阻塞,而这并非领域需求。
  • 在项目权威来源(规格说明、代码)之外单独记录模型——文档会在第一次未同步变更时与实际系统脱节。

Validação

验证

  • A linguagem usada em spec, código, UI e nomes de coluna/tabela é a mesma para o mesmo conceito, e distinta quando o conceito é distinto entre contextos.
  • Existem cenários (exemplo + contraexemplo) que exercitam cada invariante e cada transição relevante do modelo.
  • Nenhum dado tem dois owners capazes de escrever de forma concorrente e inconsistente sem coordenação explícita.
  • As decisões de modelo (glossário, invariante, boundary) estão registradas apenas na fonte autorizada do projeto, sem cópia paralela desatualizável.
  • Não declarar um modelo "correto" sem os cenários acima — um modelo sem contraexemplo testado é uma hipótese, não uma validação.
  • 规格说明、代码、UI以及数据库列/表名称中,同一概念使用相同的语言,不同上下文的不同概念使用不同的语言。
  • 存在能够覆盖每个Invariant和模型相关转换的场景(示例+反例)。
  • 没有任何数据存在两个可并发写入且无明确协调的负责人,导致不一致。
  • 模型决策(术语表、Invariant、边界)仅记录在项目的权威来源中,不存在可过时的并行副本。
  • 不要在没有上述场景的情况下宣称模型“正确”——未经过反例测试的模型只是假设,而非验证后的结果。

Skills relacionadas

相关技能

  • $specsfy-specialist-merge-conflict-resolution
    preserva intenção quando conflitos atingem nomes e invariantes do modelo.
  • $specsfy-specialist-prototyping
    testa hipóteses do domínio sem promover o protótipo a fonte normativa.
  • $specsfy-specialist-ux-design
    valida o vocabulário na jornada e
    $specsfy-specialist-web-api-design
    o expõe como contrato público sem transferir ownership.
  • $specsfy-specialist-software-architecture
    quando um bounded context novo implicar um boundary de serviço, banco ou deployment.
  • $specsfy-specialist-technical-research
    quando a decisão de modelo depender de como um sistema externo já define o mesmo conceito.
Leia references/standards.md para artefatos de modelagem, perguntas-guia, e as fontes primárias de DDD e event storming.
  • $specsfy-specialist-merge-conflict-resolution
    :当冲突涉及模型名称和Invariant时,保留设计意图。
  • $specsfy-specialist-prototyping
    :测试领域假设,而不将原型作为规范来源。
  • $specsfy-specialist-ux-design
    :在用户旅程中验证词汇,
    $specsfy-specialist-web-api-design
    将其作为公共契约暴露,且不转移所有权。
  • $specsfy-specialist-software-architecture
    :当新的Bounded Context意味着需要新的服务、数据库或部署边界时使用。
  • $specsfy-specialist-technical-research
    :当模型决策依赖外部系统对同一概念的定义时使用。
阅读references/standards.md获取建模工件、指导问题以及DDD和Event Storming的主要来源。