Como aplicar os princípios de SOLID em aplicações feitas com React.
Atualmente os princípios de SOLID e a filosofia de Clean Code estão em alta no mundo do desenvolvimento, segui-los na maioria dos casos resultará em um código mais limpo e inteligível.
Single Responsibility
Uma classe deve ter um, e apenas um, motivo para ser modificada.
Pelo nome já é possível ter uma noção do que se trata, seguir esse princípio no React é basicamente criar componentes e funções com uma única utilidade.
O exemplo acima demonstra como podemos fazer um componente com a única utilidade de renderizar um título e que pode ser reaproveitado em diversos lugares.
É claro que esse conceito pode ser usado para componentes que englobam mais ações, por exemplo um componente que executa uma request e renderiza os dados.
Podemos aplicar esse conceito na hora de criarmos os nossos Hooks também.
Nesse exemplo, temos um hook para gerenciar uma todo list, com cada funcão tendo uma responsabilidade específica, nesse cenário adaptamos o conceito do SRP não no nível de classe, mas de funções.
Open Closed
Este princípio afirma que “entidades de software (classes, módulos, funções, etc.) devem ser abertas para extensão, mas fechadas para modificação”.
Seguindo o modelo de composição¹ do React, conseguimos utilizar esse princípio dessa forma:
Aqui nós temos o componente TodoList no qual passamos a lista de todos e a função para removê-los.
Nós poderíamos ter colocado os componentes de títulos dentro do componente TodoList, porém teríamos que fazer uma verificação de tipo na hora de renderizar e a cada novo tipo de todo list teríamos que alterá-lo, ferindo a premissa do OCP, desse modo conseguimos deixar o TodoList fechado para modificações mas aberto para novas extensões e propriedades.
Liskov Substitution
“Os objetos em um programa devem ser substituídos por instâncias de seus subtipos sem alterar a exatidão desse programa.”
Utilizando TypeScript, consiguimos utilizar esse princípio dessa forma.
Nesse exemplo, o componente TodoNode serve como uma interface genérica de componentes Todo, dessa forma seguimos o LSP e podemos alternar na interface diferentes tipos de componentes Todo.
Pode ser muito útil usar essa estratégia quando for necessário adicionar alguma feature ou mudanças a nível global em um projeto, por exemplo: se precisarmos alterar os elementos de <li> pra <div>, fica mais fácil quando temos esse tipo de encapsulamento.
Interface Segregation
“Muitas interfaces específicas são melhores do que uma interface de uso geral.”
Esse princípio é utilizado em linguagens que tenham uma tipagem forte e que tenham interfaces.
Utilizá-lo no React com TypeScript é basicamente criar interfaces enxutas, segregadas e específicas para o componente.
Dependency Inversion
“Programe voltado para interface, não para a implementação”
Abaixo temos um exemplo bem simples de como implementar a inversão de dependência, basicamente acoplamos a funcionalidade das libs moment e date-fns na função chamada formatDate. No caso de alguma dessas libs ficar deprecated ou for descontinuada, como no caso do moment, só alteramos o fornecedor nessa função, sem precisar de refatorar diversas partes do sistema.
Exemplo no Codesanbox
Conclusão
Utilizar os princípios do SOLID é uma boa saída quando pensamos em qualidade de código, mas claro que em alguns cenários não precisamos seguir à risca os princípios.
Como diria o Robert C. Martin, “A dogmatic or religious application of the SOLID principles is neither realistic nor beneficial”.
Então sempre verifique e pense se vale a pena seguir os princípios, mas lógico que entendê-los, é algo extremamente importante hoje em dia quando pensamos em clean code.
Autor: Dennis Kaffer
Sobre: Dennis programa há mais de dez anos e atua como desenvolvedor no mercado de trabalho há 8 anos.
Atualmente está focado em front-end, mas gosta de quase tudo que envolva programação.
Referências
1 – https://reactjs.org/docs/composition-vs-inheritance.html
2 – https://medium.com/docler-engineering/applying-solid-to-react-ca6d1ff926a4