Modelando o domínio
No coraΓ§Γ£o de qualquer aplicaΓ§Γ£o orientada a domΓnio estΓ‘ o modelo que representa o conhecimento central e as regras de negΓ³cio do sistema. Modelar bem o domΓnio significa traduzir conceitos do mundo real em estruturas de software expressivas, coesas e consistentes.
Entidades
Uma entidade Γ© um objeto definido principalmente pela sua identidade e nΓ£o apenas pelos seus atributos. Mesmo que os atributos mudem ao longo do tempo, a identidade de uma entidade permanece a mesma.
CaracterΓsticas principais:
- Possui uma identidade ΓΊnica (geralmente um
Id
). - Aquilo que importa Γ© quem a entidade Γ©, nΓ£o apenas o que ela contΓ©m.
- Seus atributos podem mudar ao longo do tempo.
Criando uma entidade com o Lino
Para criar uma nova entidade utilizando o Lino, execute:
lino entity new
O assistente do CLI solicitarΓ‘:
- ServiΓ§o β ServiΓ§o no qual a entidade serΓ‘ criada.
- MΓ³dulo β MΓ³dulo em que a entidade serΓ‘ criada (apenas em serviΓ§os modulares).
- Nome da entidade β Nome utilizado no domΓnio e na tabela do banco de dados.
Em seguida, vocΓͺ definirΓ‘ os campos que compΓ΅em a entidade, configurando cada um deles.
Tipos de campos disponΓveis
Tipo | DescriΓ§Γ£o | Faixa / ObservaΓ§Γ΅es |
---|---|---|
short | Inteiro de 16 bits | -32β―768 β 32β―767 |
int | Inteiro de 32 bits | -2β―147β―483β―648 β 2β―147β―483β―647 |
long | Inteiro de 64 bits | -9β―223β―372β―036β―854β―775β―808 β 9β―223β―372β―036β―854β―775β―807 |
string | Texto | AtΓ© ~2 bilhΓ΅es de caracteres |
bool | Valor booleano | true ou false |
Guid | Identificador global ΓΊnico | Unicidade distribuΓda |
decimal | NΓΊmero decimal de alta precisΓ£o | Ideal p/ valores monetΓ‘rios |
float | Ponto flutuante (32 bits) | ββ―6β9 dΓgitos de precisΓ£o |
double | Ponto flutuante (64 bits) | ββ―15β17 dΓgitos de precisΓ£o |
DateTime | Data e hora | Inclui fuso horΓ‘rio |
DateOnly | SΓ³ data (C#Β 10+) | β |
TimeOnly | SΓ³ hora (C#Β 10+) | β |
Entity | ReferΓͺncia a outra entidade | 1 : 1 ou 1 : N |
Value Object | Objeto de valor imutΓ‘vel | Ex.: EndereΓ§o, CPF |
Enum | EnumeraΓ§Γ£o | Conjunto fixo de valores |
List<Entity> | Lista de entidades | 1 : N |
ManyToMany | Muitosβparaβmuitos | Requer tabela de junΓ§Γ£o |
Exemplo
Criando a entidade Person
:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββ¬βββββββββ¬ββββββββββββ¬βββββββββββββββββ β PK β FK β Property name β Type β Length β Required β Auto-increment β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββΌβββββββββββββββββ€ β x β β Id β int β β x β x β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββΌβββββββββββββββββ€ β β β Name β string β 100 β x β β ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ΄βββββββββββββββββ
Estrutura gerada pelo Lino:
MyApp/ βββ src/ βββ Services/ βββ MyService/ βββ Domain/ βββ MyApp.MyService.Domain.csproj βββ Aggregates/ βββ People/ βββ Person.cs βββ Errors/ β βββ PersonErrors.cs βββ Repositories/ β βββ IPersonRepository.cs βββ Resources/ βββ Person/ βββ PersonResources.resx βββ PersonResources.en.resx βββ PersonResources.pt-BR.resx
Depois de definir suas entidades, use o prΓ³prio Lino para gerenciar as Migrations e manter o banco de dados sincronizado. Abordaremos esse processo em detalhes na seΓ§Γ£o Camada de PersistΓͺncia.
Objetos de Valor
Um objeto de valor representa um conceito do domΓnio definido apenas pelos seus atributos β ele nΓ£o possui identidade prΓ³pria. Dois objetos de valor sΓ£o considerados iguais se todos os seus valores forem iguais.
CaracterΓsticas principais:
- ImutΓ‘veis apΓ³s a criaΓ§Γ£o.
- NΓ£o possuem
Id
.
Criando um objeto de valor com o Lino
Execute:
lino value-object new
O CLI solicitarΓ‘:
- ServiΓ§o β ServiΓ§o no qual o objeto serΓ‘ criado.
- MΓ³dulo β MΓ³dulo em que o objeto serΓ‘ criado (apenas em serviΓ§os modulares).
- LocalizaΓ§Γ£o β Raiz do domΓnio ou agregado especΓfico.
- Nome do objeto de valor.
Em seguida, defina os campos que compΓ΅em o objeto.
Tipos de campos disponΓveis
Tipo | DescriΓ§Γ£o | ObservaΓ§Γ΅es |
---|---|---|
short | Inteiro de 16 bits | -32β―768 β 32β―767 |
int | Inteiro de 32 bits | -2β―147β―483β―648 β 2β―147β―483β―647 |
long | Inteiro de 64 bits | -9β―223β―372β―036β―854β―775β―808 β 9β―223β―372β―036β―854β―775β―807 |
string | Texto | AtΓ© ~2 bilhΓ΅es de caracteres |
bool | Booleano | true /false |
decimal | Decimal preciso | Valores monetΓ‘rios |
float | Ponto flutuante (32 bits) | ββ―6β9 dΓgitos |
double | Ponto flutuante (64 bits) | ββ―15β17 dΓgitos |
DateTime | Data/hora | Inclui fuso |
DateOnly | Somente data | C#Β 10+ |
TimeOnly | Somente hora | C#Β 10+ |
Exemplo
Objeto de valor Address
:
βββββββββββββββββ¬βββββββββ¬βββββββββ¬ββββββββββββ β Property name β Type β Length β Required β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Street β string β 100 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Number β string β 10 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Neighborhood β string β 50 β β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β City β string β 100 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β State β string β 2 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β PostalCode β string β 20 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Country β string β 100 β x β βββββββββββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ
Estrutura de arquivos gerada (agregado Person
):
MyApp/ βββ src/ βββ Services/ βββ MyService/ βββ Domain/ βββ MyApp.MyService.Domain.csproj βββ Aggregates/ βββ People/ βββ Person.cs βββ ValueObjects/ β βββ Address.cs βββ Errors/ β βββ AddressErrors.cs β βββ PersonErrors.cs βββ Repositories/ β βββ IPersonRepository.cs βββ Resources/ βββ Address/ β βββ AddressResources.resx β βββ AddressResources.en.resx β βββ AddressResources.pt-BR.resx βββ Person/ βββ PersonResources.resx βββ PersonResources.en.resx βββ PersonResources.pt-BR.resx
Assim como nas entidades, as Migrations podem ser gerenciadas pelo Lino para manter o modelo de dados em sincronia.
EnumeraΓ§Γ΅es
As enumeraΓ§Γ΅es em DDD podem ir alΓ©m dos enum
tradicionais do C#. Elas podem ser objetos ricos
que representam estados fixos, contendo validaΓ§Γ΅es, mΓ©todos auxiliares e atΓ© comportamento.
MotivaΓ§Γ£o:
- Os
enum
do C# sΓ£o limitados a um valor inteiro ou string. - Modelar uma Enumeration como classe oferece maior flexibilidade e expressividade.
CaracterΓsticas principais:
- SΓ£o classes que herdam de uma base comum e encapsulam
Id
eNome
. - Permitem adicionar validaΓ§Γ΅es, mΓ©todos auxiliares e comportamento.
Criando uma enumeraΓ§Γ£o com o Lino
Execute:
lino enum new
O assistente solicitarΓ‘:
- ServiΓ§o.
- MΓ³dulo (se aplicΓ‘vel).
- LocalizaΓ§Γ£o β Raiz do domΓnio ou agregado.
- Nome da enumeraΓ§Γ£o.
- Tipo β
enum
tradicional ou Smart Enum (class
). - Armazenamento β
int
oustring
no banco de dados.
Exemplo
EnumeraΓ§Γ£o PersonStatus
:
βββββββββ¬ββββββββββββ¬βββββββββββββββ β Value β Name β Display Name β βββββββββΌββββββββββββΌβββββββββββββββ€ β 1 β Active β Active β βββββββββΌββββββββββββΌβββββββββββββββ€ β 2 β Inactive β Inactive β βββββββββΌββββββββββββΌβββββββββββββββ€ β 3 β Suspended β Suspended β βββββββββΌββββββββββββΌβββββββββββββββ€ β 4 β Deleted β Deleted β βββββββββ΄ββββββββββββ΄βββββββββββββββ
Estrutura gerada:
MyApp/ βββ src/ βββ Services/ βββ MyService/ βββ Domain/ βββ MyApp.MyService.Domain.csproj βββ Aggregates/ βββ People/ βββ Person.cs βββ Enums/ β βββ PersonStatus.cs βββ ValueObjects/ β βββ Address.cs βββ Errors/ β βββ AddressErrors.cs β βββ PersonErrors.cs βββ Repositories/ β βββ IPersonRepository.cs βββ Resources/ βββ Address/ β βββ AddressResources.resx β βββ AddressResources.en.resx β βββ AddressResources.pt-BR.resx βββ Person/ β βββ PersonResources.resx β βββ PersonResources.en.resx β βββ PersonResources.pt-BR.resx βββ PersonStatus/ βββ PersonStatusResources.resx βββ PersonStatusResources.en.resx βββ PersonStatusResources.pt-BR.resx
Armazenar o valor de uma enumeraΓ§Γ£o como string
Γ© vΓ‘lido e pode melhorar a legibilidade, mas tende a ser menos eficiente em termos de desempenho e armazenamento.
Por isso, recomendamos armazenar o valor como int
, e, para manter a integridade referencial e facilitar a manutenΓ§Γ£o, criar uma entidade (tabela) auxiliar onde a chave primΓ‘ria corresponda ao valor da enumeraΓ§Γ£o.
ApΓ³s definir as enumeraΓ§Γ΅es, utilize o Lino para gerar e aplicar as Migrations, garantindo que o banco de dados reflita o modelo de domΓnio. Veja detalhes na seΓ§Γ£o Camada de PersistΓͺncia.