Artigo

Um use case pode chamar o outro?

Rodrigo Branas
Rodrigo Branas
20 jun 2023·5 min de leitura
#clean-architecture#use-case

Esse talvez seja o grande dilema de quem comeca no Clean Architecture, e a pergunta que todos sempre fazem e precisamos levar alguns aspectos em consideracao antes de responder.

Normalmente essa necessidade vem da falta de um Domain Model, que no Clean Architecture e representado pela camada de entities. Essa camada e responsavel pelas regras de negocio independentes, que podem ser utilizadas e orquestradas pelos use cases para entregar o comportamento desejado pelos usuários.

As entities não são necessariamente objetos, podem ser meras funcoes, estruturas de dados, esse conceito não esta associado necessariamente a um design orientado a objetos.

Qual e a diferença entre uma entity para um use case?

Imagine dois objetos Coordenada, com as propriedades latitude e longitude. E possível escrever um algoritmo que retorna a distância entre eles? Isso parece uma regra de negocio independente?

Com certeza! Essa regra de negocio não depende de nenhum recurso externo, e baseado apenas nos parametros de entrada e e possível criar um teste de unidade.

Qual use case poderia utilizar essa regra de negocio, por exemplo:

  • Ao fazer uma compra na Amazon e necessario calcular a distância entre o centro de distribuição e o comprador para calcular o frete
  • Quando solicitamos uma corrida no Uber precisamos calcular a distância entre a origem e o destino para estimar o preço
  • Para registrar a distância percorrida em um treino do Strava podemos utilizar o mesmo algoritmo

Repare que normalmente os usuários desses casos de uso não estão interessados nas regras de negocio independentes fornecidas pelas entities, ou alguém entra na Amazon pra calcular a distância entre dois pontos geograficos? No entanto, elas são fundamentais para a implementação dos use cases.

Quem esta acostumado com um modelo anemico, aquele que o Martin Fowler chama de Transaction Script, esta condicionado a pensar de forma procedural, onde toda regra esta espalhada em algo com o sufixo Service e os objetos são meras estruturas de transporte de dados, sem comportamento.

Não é uma questao de funcionar ou não, e so um design diferente, como todos, tem vantagens e desvantagens. A desvantagem e não conseguir dividir bem a complexidade, acoplando regras independentes em recursos externos, prejudicando o reuso e dificultando os testes.

Não confunda as entities do Clean Architecture com as entities de um ORM

No ORM, uma entity faz um mapeamento entre um objeto e uma tabela do banco de dados e essa responsabilidade não deve ser misturada com as regras de negocio, não so porquê elas mudam por motivos diferentes, quebrando o SRP, mas porque estão em camadas diferentes.

Voltando ao assunto, você já definiu uma camada de entities e ainda sente a necessidade de fazer um use case chamar o outro, caso contrario estara duplicando muito código?

Talvez seja necessario entender como os objetos de domínio estão sendo agrupados, e o que o Domain-Driven Design chama de aggregate e e um conceito pouco abordado no Clean Architecture.

A ideia Não é ter entidades totalmente separadas umas das outras, isso naturalmente aumentaria a responsabilidade dos use cases. Ao inves disso, os aggregates devem assumir esse papel, de Facade ou Facade (como o padrao do GoF), orquestrando a interação entre os objetos de domínio pertencentes a ele e com isso reduzindo o acoplamento entre os use cases e as entities.

Você já fez tudo isso, tem seus aggregates e repositories bem definidos e continua sentindo a necessidade de fazer um use case chamar o outro?

Eu sei exatamente onde estamos indo. Existem duas situacoes onde isso pode acontecer!

A primeira e quando existem casos de uso levemente diferentes, por exemplo:

  • Criar conteúdo
  • Copiar conteúdo
  • Importar conteúdo

Repare que todos eles de fato criam um conteúdo em um curso, a diferença e que copiar conteúdo cria um conteúdo a partir de dados de um conteúdo existente e importar conteúdo cria um conteúdo com base em um arquivo externo, provavelmente uma planilha exportada de outro sistema.

Nesses casos e como se existisse um Decorator ao redor do caso de uso principal, imagine, e o mesmo comportamento, a diferença e que em copiar a origem e um conteúdo já existente, ou seja, e como se um use case incorporasse o outro. No caso do importar e a mesma coisa, a diferença e que vamos percorrer uma lista e chamar o use case de criar conteúdo tantas vezes quanto for necessario.

Não vejo problemas em fazer um use case chamar o outro nessas situacoes, simplesmente não faz sentido copiar a maior parte de um use case em outro apenas para mudar a forma como ele e utilizado.

No entanto, existem duas ressalvas. A primeira e, tome cuidado com a quebra do SRP, ou Single Responsibility Principle. Se você começar a mudar o use case principal por demandas introduzidas por outros use cases isso pode trazer muita fragilidade, quebrando os outros use cases dependentes, e complexidade adicional para o use case principal, por isso avalie se copiar e seguir caminhos diferentes Não é a melhor opção.

A segunda ressalva tem relação com resiliencia, estabilidade e performance. Imagina chamar o use case importar conteúdo com uma lista de 100 mil conteúdos. Pode não ser o caso, mas se for talvez seja melhor investir em padrões como um Command Handler, jogando as solicitacoes em uma fila e consumindo aos poucos, conforme a disponibilidade de recursos.

Utilize eventos de domínio

Por fim, e se esse outro use case fizesse parte de uma transacao de longa duração, por exemplo, ao finalizar uma corrida e necessario processar o pagamento, depois emitir uma nota fiscal, enviar um email com o comprovante para o cliente, solicitar a avaliação da corrida e assim por diante.

Talvez esses use cases estejam até mesmo em bounded contexts diferentes e utilizar eventos vai proporcionar um acoplamento mais baixo, além de uma relação mais resiliente entre eles.

Por exemplo, caso o bounded context, que normalmente e um bom ponto de divisao de microservices, responsavel pela comunicação esteja fora do ar, quando ele voltar vai processar as mensagens pendentes e enviar o comprovante ao cliente.

Isso contribui principalmente para aumentar a escalabilidade, independência e resiliencia da sua arquitetura.

Conclusão

Nesse ponto você já entendeu que tem varias opcoes antes de fazer um use case simplesmente chamar o outro. A partir daqui, a decisão e sua.

Lembre-se que os autores escrevem livros que são reflexo do seu ponto de vista, das suas proprias experiências e não são leis ou regras que você esta deixando de cumprir.

A sua realidade será diferente e a responsabilidade por cada decisão será sempre sua, então aprenda a colocar na balança os pros e contras de cada uma delas.

Quer fazer um use case chamar o outro, excelente, coloque na balança o que você ganha e o que você perde e como lidar com isso ao longo do tempo.

Continue aprendendo

Já conhece nossas formações?

Os desenvolvedores que vão se manter no futuro são os que dominam a Inteligência Artificial e são arquitetos de software. Aprenda como ser esse tipo de desenvolvedor.

Cookies e privacidade

Utilizamos cookies para melhorar sua experiência, analisar o tráfego do site e personalizar conteúdo. Você pode aceitar todos, rejeitar ou personalizar suas preferências.