Executando verificação de segurança...
5
Zaqueu
2 min de leitura ·

🏷️ Você usa UUID pra tudo?

𝐏𝐫𝐢𝐦𝐢𝐭𝐢𝐯𝐞 𝐎𝐛𝐬𝐞𝐬𝐬𝐢𝐨𝐧 é um anti-pattern dentro do 𝐃𝐨𝐦𝐚𝐢𝐧 𝐃𝐫𝐢𝐯𝐞𝐧 𝐃𝐞𝐬𝐢𝐠𝐧, sendo caracterizado pelo uso excessivo de tipos primitivos (string, int, uuid...) para representar conceitos de domínio.

Isso deixa o domínio menos expressivo, dificultando seu entendimento.

Vamos para um caso de uso mais completo, retirado do 𝐒𝐲𝐤𝐢 (https://github.com/ZaqueuCavalcante/syki), um sistema de gerenciamento de instituições de ensino open-source.

Na imagem do post temos o conceito de Comando, que se relaciona com outras entidades do sistema:

• Um Comando pertence à uma Instituição de Ensino
• Um Comando pode ser gerado por um Evento de Domínio
• Um Comando pode ser gerado por outro Comando
• Um Comando pode estar agrupado dentro de um Lote de Comandos

Na parte superior da imagem, todos esses relacionamentos são feitos através de UUIDs, logo é preciso muita atenção do desenvolvedor para não passar o id de um evento no lugar do de um comando/lote por exemplo.

Pensando nisso, podemos utilizar ids fortemente tipados para evitar esses erros, como mostrado na parte inferior da imagem. Dessa forma, todos os lugares que referenciem o id de um comando precisam possuir a tipagem correta (CommandId) ao invés da tipagem mais genérica (Guid). O mesmo se aplica aos demais ids (InstitutionId, DomainEventId e CommandBatchId).

Na implementação utilizei a biblioteca StronglyTypedId (https://github.com/andrewlock/StronglyTypedId), criada pelo Andrew Lock.

Você já usa essa abordagem nos seus sistemas? Está pensando em usar? Deixe sua opinião nos comentários, vlw!

Carregando publicação patrocinada...
5

Abstraction Obsession também é um antipattern, mas pouco popular, o que não o toirno menos válido. O que usar é algo que depende de contexto e muita experiência, mas o maior antipattern é usar tudo como receita de bolo.

O assunto foi tratado esses dias sob outro prisma: https://www.tabnews.com.br/maniero/741ea32b-e5f0-4bfa-8e01-93b1733a89d0.

Primeiro deveria pensar se deve usar UUID ou algo parecido, isso começou virar um padrão as pessoas adotarem sem pensar se é útil e se vale o preço que tem que pagar com ele.

Este caso pode ser interessante a abstração para evitar ter que vincular o id com a implementação de UUID, mas poucas pessoas conseguem fazer uma boa abstração para esse id e que se mudar a implementação internet que passe usar um UUID ou deixe de usar e tudo continue funcionando. Nesse ponto eu sou um pouco crítico das abstrações (que podem ser ótimas) porque é muito difícil não ter vazamento de abstração.

Vou me abster de falar sobre DDD, talvez hoje a técnica mais interessante e útil que é mais mal-usada e adotada onde não deve porque a modinha é mais importante. Inclusive uma das coisas que o DDD induz é fazer tudo como se o futuro do sistema pudesse ser tão controlado e os recursos usados não importam.

Obrigado pelo link, olhando por cima não sei se é uma boa implementação, mas no mínimo pode ser útil para fazer algo melhor, se não for, com um bom começo.

S2


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente (não vendo nada, é retribuição na minha aposentadoria) (links aqui no perfil também).

3

É a história de quando se é bom com um martelo, todo problema parece um prego.
UUID é incrível, mas não é bom para tudo, você tem que pesar vantagens e desvantagens.
Por exemplo, se você precisa frequentemente executar consultas diretamente no banco de dados, é um pesadelo fazer coisas como

SELECT UserId, UserName
FROM Users
WHERE UserId = '93799589-6875-4b60-9673-2a95180b4803'

Esta é uma query simples, mas acrescente multiplos JOINs, subqueries, etc e veja onde vai parar

Eu gosto MUITO de UUIDs, mas eu tento usar em locais especificos, como por exemplo se vou precisar usar num ambiente de microserviços, ou se vou precisar que a mesma entidade funcione em sistemas heterogêneos, ou se preciso criar toda uma arvore de entidades no cliente antes de enviar para o servidor

1

uuid pode ser usado exatamente como um id incremental sem prejuízo, desde que seja passível de ordenamento. Pode colocar joins e afins e terá performance similar a outras saídas... uma sugestão é usar o uuid v7, que já implementa isso