Single Responsibility Principle, Common-Closure Principle e a remoção dos acoplamentos na arquitetura
Se uma classe muda por diferentes razões e provoca alterações em diversas camadas, sua arquitetura pode ter um problema.
Escrever código para entregar o software funcionando e ignorar a sua evolução e manutenção, é um dos maiores erros que temos cometido como desenvolvedores ao longo de todos esses anos. O custo de manutenção e evolução do software torna-se absurdamente alto se no passado os desenvolvedores não se atentaram para a necessidade de ter um baixo acoplamento e deixaram de lado alguns princípios fundamentais. Nesse post, abordaremos brevemente os princípios Single Responsibility e Common-Closure e como eles são importantes para manter o baixo acoplamento na arquitetura.
︎︎▶︎ Single Responsibility Principle (SRP)
Single Responsibility Principle nos diz que uma classe ou método deve ter uma única razão para mudar, e consequentemente uma única responsabilidade.
▶︎ Common-Closure Principle (CCP)
Common-Closure Principle afirma que um componente não deve ter mais de uma razão para mudar e que as classes que estão fortemente relacionadas devem ser agrupadas no mesmo componente. O CCP é a versão do SRP aplicado à componentes.
Reúna as coisas que mudam ao mesmo tempo e pelas mesmas razões. Separe as coisas que mudam em momentos diferentes ou por motivos diferentes.
Nem tudo é o que parece
Buscamos incansavelmente promover o reúso de código, eliminando duplicações e acelerando a nossa produtividade. Essa é uma tarefa extremamente importante, porém deve ser feita com muito cuidado, separando responsabilidades de modo que os princípios SRP e CCP não sejam violados. Por exemplo, podemos ficar tentados à reutilizar objetos de entidades da camada de Domínio como modelos de request/response pela falsa impressão que são a mesma coisa, e criar um objeto só para receber os dados da API parece "duplicidade".
Imagine uma aplicação semelhante à Netflix que tenha um catálogo de filmes. Ao clicar em um determinado filme o usuário consegue ver as informações do filme e a sua popularidade. Para isso, a aplicação busca as informações em uma API externa.
Como aparentemente a API já devolve os dados que serão exibidos, vamos reutilizar o objeto Movie
da camada de Domínio para receber os dados da API (emExternalAPI
).
Tudo parece Ok, porém se em algum momento a API externa precisar alterar o tipo do campo popularity
para Float
? Essa alteração irá propagar modificações por todas as camadas que utilizam a entidade Movie
do Domínio. Mas deveria? 🤔
Não deveria. Isso ocorreu porque violamos o SRP e o CCP. A alteração aconteceu em um detalhe de implementação da camada de Data e não deveria impactar o Domínio da aplicação.
Vamos reproduzir o mesmo cenário, porém adicionando um modelo de response para receber os dados da API na camada de Data.
Adicionando o modelo MovieResponse
conseguimos manter nosso Domínio livre de acoplamento, pois se uma alteração semelhante à citada anteriormente acontecer, somente a camada Data será impactada, assim como vimos no Common-Closure Principle. Além disso, temos duas classes diferentes Movie
e MovieResponse
, cada uma com sua responsabilidade (SRP). O propósito desses objetos são muito diferentes e eles mudam por razões diferentes também.
Lembre-se sempre: precisamos criar softwares que sejam fáceis de manter e evoluir.
De todos os aspectos de um software, a manutenção é a mais cara. As implementações intermináveis de novas features e a inevitável trilha de bugs e correções consomem grandes quantidades de recursos.
Alguns pontos de atenção
- O Domínio da aplicação é o que reflete o negócio. Ele deve ser isolado e totalmente independente;
- Somente alterações a nível de negócio devem impactar o Domínio. Caso outras modificações te obrigue a alterar algo no Domínio, pode ser um forte indício que há acoplamento em sua arquitetura;
- Esteja bem atento as decisões a nível de Domínio. Todo o resto do software existe apenas para apoiá-lo.
Referências
Muito obrigado por ter lido até aqui!! Se você gostou desse post, não deixe de compartilhar 😁👍🏻