🇧🇷 Guia para modelagem de domínios ricos

Arley Pádua
Sep 1, 2018 · 2 min read

Vou iniciar esse artigo com um exemplo de classe e fazer a pergunta: VocĂŞ acha que o cĂłdigo abaixo Ă© um bom domain model ?

Obs.: Não há nada de errado em usar classes assim quando não há complexidade de negócio, mas você tem que ter em mente que isso não é um domain model. Isso é mais parecido com um data transfer object (DTO).

Faz um tempo que eu vejo implementações de “domain models” da maneira demonstrada acima e toda lógica de manipulação dessas classes é colocada em outro lugar, muitas vezes chamado de “XyzService”, no nosso exemplo “OrderService”:

Ambos exemplos mostram o que se chama de modelos de domínio anêmico, ou em inglês anemic domain model. Assunto muito bem argumentado por Marin Fowler. Também de acordo com ele, um modelo de domínio é um modelo de objeto do domínio que incorpora comportamento e dados.

Se refatorarmos o cĂłdigo e colocarmos comportamento e dados na mesma classe, o modelo Order se torna mais claro e mostra o seu objetivo:

Agora parece melhor.

Mas agora, o que aconteceria ao construir a classe e adicionar um item ao pedido ?

BOOM! Null Reference Exception, porque o nosso modelo de domínio ainda precisa de um gerenciamento de estado e a lista de itens está nula.

O objeto deve encapsular a maneira que ele é construído, modificado e se manter em um estado válido.

Vamos modificar a classe com private setters e construtores privados, evitando que algum código externo construa/altere o objeto em um estado inválido.

Precisamos de uma maneira de criar o pedido. Vamos adicionar um método que é capaz de criar um pedido em um estado válido:

O mesmo para a classe OrderItem:

Se a classe Order for consumida por um código externo, a única opção que é exposta para criá-la é usando o método “New”. Não será possível alterar o estado em um código externo, pois suas propriedades são somente leitura do ponto de vista externo.

É possível notar que a nossa classe Order tem uma propriedade que armazena uma lista de itens de um pedido e um método chamado AddItem() usado para adicionar itens validos ao pedido. Mesmo assim, um código externo pode acessar a propriedade de lista e adicionar um item sem validação, uma vez que o objeto List do framework é mutável.

Uma maneira de solucionar essa questão é sempre expor uma cópia imutável dos itens e encapsular a lista original:

Com essa alteração, a entidade pode modificar a lista e códigos externos podem ver a lista sem modificá-la.

Aplicando esses passos, temos uma classe completamente independente, incorruptível e auto gerenciável.

Para ver o resultado final das classes, acesse o gist.

Este artigo também está disponível em Inglês.

Software Engineer and passionate about distributed systems done right

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade