🇧🇷 Guia para modelagem de domínios ricos

Arley Pádua
2 min readSep 1, 2018

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.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Arley Pádua
Arley Pádua

Written by Arley Pádua

Software Engineer and passionate about distributed systems

Responses (1)

Write a response

Uma recomendação é evitar a adição de itens através de
order.Itens.Add(),
uma vez que order é uma raiz de agregação, as alterações na raiz de agregado ou em suas entidades deveriam ser feitas através de métodos da raiz de agregado. Assim ficaria:
order…