Estou com dúvida em relação a camada de domínio vs infraestrutura no que tange aplicar ou não “regras de negócio” diretamente numa consulta a banco. Segue abaixo descrição do cenário:
Tenho uma funcionalidade de notificação por mensagens, sempre que o usuário se loga todas as mensagens destinadas a ele são carregadas, ocorre que isso está onerando o banco.
Para exibir as mensagens pro usuário é aplicado uma regra de negócio que atualmente está na entidade de domínio, porém pra resolver o problema de performance eu poderia aplicar essa regra diretamente na query(Regra: é possível cadastrar mensagens com prazo de expiração, nesse caso serão exibidas somente as mensagens no prazo de validade).
Dúvida 1: filtro no banco levando a regra de negócio pra lá ou carrego todas as mensagens em memória, onerando o banco, e depois aplico a regra de negócio na entidade de domínio.
Dúvida 2: vocês consideram esse filtro por uma coluna da tabela sendo realizado na query como regra de negócio?
Seguindo as boas práticas de manter o domínio da aplicação independente da infra, como vocês fazem nesse caso, que pra carregar os registros do banco em memória e depois aplicar as regras de negócio acaba gerando problemas de performance por colocar muitos dados na memória do servidor de aplicação?
Rapaiz, se for para melhorar performance, acho que deve filtrar no banco direto msm. Claro, cada caso é um caso diferente (concordo em deixar a camada de dominio o mais redonda possível), mas deixar um sistema lento e com possíveis erros de estouro de memória é complicado.
Acho que um filtro na query não eh bem uma regra de negocio, mas um aspecto téccnico usado por alguma regra de negócio.
Por exemplo, se a regra é retornar todos os usuário ativos, na consulta vc terá que filtrar apenas os usuário ativos, mas a regra msm. Sacou?
Realmente pode ser confuso, mas em termos de um domínio bem isolado, imagine que vc tenha uma interface de repositório com um método recuperarUsuariosAtivos(), isso já eh a definição da regra por parte do sistema (é o que ele precisa para implementar determinado requisito). Agora, como ele é realizado, já é um detalhe técnico (seja pelo filtro direto na query ou pelo código). Ainda mais se tratando de um aspecto não funcional, como performance.
A regra de negócio foi definida no método recuperarUsuariosAtivos(), quem que vai implementar e como não importa, entendido. Porém quando a regra de negócio foi implementada dentro do domínio testei a unidade muito facilmente, agora se jogar essa regra pro Repository vou ter que ficar mockando, isso ao meu ver é bem ruim e trabalhoso.
Concordo com o que você disse, só estou levantando outras situações que percebi e que me geraram dúvidas. Ainda estou estudando sobre como funciona esse “descolamento” da entidade de domínio de sua representação persistida.
Concordo que o que vc disse. Ao alterar isso para a query no repositório, para testar efetivamente (em relação ao filtro na query), teria que ser um teste de integração usando algum banco em memória ou alguma base de teste já preparada.
Qualquer outro código que for usar esse método do repositorio que faz esse filtro, unitário com mock resolve bem e não é ruim (como dito pelo @Jonathan_Medeiros).
Acho que me expressei mal, não quis dizer que acho ruim mockar, mas sim que antes as regras eram testadas facilmente no domínio e agora preciso realizar mais passos pra testar direto no banco. Uso mocks o tempo todo, hehe.
Quando a regra estava implementada no domínio tinha alguns casos de testes pra essa regra já implementados, como tirei a regra do domínio e mandei pro repositório apaguei o método de produção e os testes, tive um sentimento ruim ao fazer isso, hahahah.
Uma alternativa que já foi sugerida e eu considero super boa seria implementar um teste de integração nesse caso, apesar de ser um pouco mais custoso o ganho com ele neste seu cenário acredito que seria extremamente válido.