Refatorando como um modelo mental

26 Dez 2020 · 5 minutos · Loading views

Ouço frequentemente o termo refactoring sendo usado como uma solução para problemas comuns no ciclo de desenvolvimento. Eu não quero ser a pessoa irritante que diz como uma palavra tem de ser usada, mas é inegável que há uma confusão quando as pessoas o usam.

É muito comum ver o termo a ser utilizado para: correcções de bugs, abstrações e mesmo uma simples reestruturação. Vou mostrar dois exemplos para tentar desfazer um pouco da confusão que paira sobre a palavra.

Primeiro exemplo

Precisei construir um componente de lista ordenada e um dos requisitos era mostrar o número ordinal, por exemplo, 1º, 2º e 3º. De relance parece um problema simples mas é também uma armadilha perfeita para pensar sobre problemas que ainda não precisam ser resolvidos:

  • Solução: usar uma biblioteca, por exemplo Number.js?
  • Pegada: será que a biblioteca vai aumentar o tamanho do JS para o cliente?
  • Internacionalização: precisamos considerar a localização do usuário?

Apesar de me colocar regularmente no estado de overthinking, não gosto de trabalhar em problemas que ainda não existem e decidi aplicar o K.I.S.S. Vamos escrever a função mais simples possível e refatorar se necessário:

function getOrdinal(n) {
if (n > 3 && n < 21) {
return "th"
}
if (n % 10 === 1) {
return "st"
} else if (n % 10 === 2) {
return "nd"
} else if (n % 10 === 3) {
return "rd"
}
return "th"
}

Uma implementação bem simples

Nesta altura não estava preocupado com eficiência e outros tópicos. O objetivo era visualizar números ordinais na lista e isto já estava funcionando! Legal, não? 🎉

Como eu disse, a função é muito simples e há várias pequenas mudanças que, ao mesmo tempo, melhoram a implementação e mantém o resultado inalterado. Vamos substituir a estrutura condicional principal por um simples switch:

function getOrdinal(n) {
if (n > 3 && n < 21)
return 'th';
switch (n % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}

Com certeza é a primeira resposta do StackOverflow

E isso significa que acabamos de refatorar o nosso código! A implementação melhorou e o resultado continua o mesmo. 🎉

Segundo exemplo

Para a lista ordenada no exemplo anterior, precisava fazer uma requisição HTTP e pegar a lista de usuários. Como o projeto é escrito utilizando React, me vali de um hook para reaproveitar a lógica:

function useUsers() {
return useQuery("user-list",
() => getUsers()
));
}

direto ao ponto com react-query 🎉

Pela natureza da resposta do servidor acabamos com uma estrutura complexa aninhada, por exemplodata.data.users.

E como data.data.users pode não estar sempre definido, e o mesmo vale para suas propriedades aninhadas, os componentes precisavam conferir se as propriedades estavam definidas diversas vezes.

<ComponentA
propA={data?.data}
/>
// or even
{
data?.
data?.
users.length > 0 ?
<ComponentA /> :
null
}

Conferindo undefined para sempre

Esse exemplo funciona e conseguimos renderizar a lista de usuários, mas também introduz padrões estranhos dentro do código. Parece algo que podemos refatorar, certo?

Nesse caso, uma simples transformação da resposta da API já funciona: simplificamos o que o componente precisa consumir and isolamos as responsabilidades. Vamos ver como ficaria:

export function useUsers() {
return useQuery("list-users",
() => getUsers(), {
// select let's us transform a response ;)
select: (data) => {
return {
...data.data,
};
},
});
}
// E os components:
{
data.users.length > 0 ?
<ComponentA /> :
null
}

uhul!

Nesse caso mudamos apenas algumas linhas na camada de serviços e nos desfazemos com sucesso de inconsistências no código. Um refatoramento pequeno que melhorou o design e manteve a funcionalidade.

Quando refatorar

Agora que delineamos o que é o refatoramento: quando devemos refatorar? Resposta curta: sempre. Mas a realidade é que esta questão é uma das questões mais negligenciadas na história recente da computação, de uma maneira geral.

Refatorar deveria ser uma prática comum, um modelo mental. Quando escrevemos código com esse modelo mental, alguns aspectos do ciclo de desenvolvimento tornam-se mais eficientes:

  • Entregas ficam rápidas e o seu consumidor final vê o resultado mais cedo
  • Melhorias e novas funcionalidades são menos custosas
  • Testar fica bem mais fácil

Refatorando como um modelo mental 🤯

A idéia é sempre escrever de maneira mais simples e determinística afim de resolver um problema. Itere no código, melhore o design e mantenha a funcionalidade. Teste. Repita. Durante esse processo, adicionar novas funcionalidades e melhorias fica muito mais fácil já que, ainda, não há complexidade envolvida!

O que eu amo mais dessa maneira de pensar é que reduz drasticamente o sentimento de paralisia pro análise. Ajuda a manter na mente que nem todos os programas precisam nascer com a abstração perfeita desde o primeiro dia e que é tudo bem não seguir o DRY as vezes.

Esse modelo pode ajudar qualquer time a entregar mais rápido. O código é simples desde o primeiro dia. E se o código for simples, os testes tornam-se mais fáceis. O objetivo final é fazer do refatoramento um hábito saudável, mesmo quando adicionando novas funcionalidades ao código. Lucro! 💰

Uma empresa inteira pode se beneficiar disso porque menos bugs significa menos dinheiro gasto com programadores consertando-os e menos usuários frustrados. External

Idéias similares

Um aviso rápido: eu não inventei isso da noite para o dia. Existem diversas fontes disponíveis de onde estudei e vivenciei para manter esse jeito de pensar. Posso recomendar algumas:

Conclusão

  • Refatorar é uma prática contínua que devemos ter como guia não importa se estamos adicionand uma nova funcionalidade, consertando um bug ou apenas escrevendo testes.
  • Foque no que importa: as vezes, repetir o código é tudo o que precisamos.(Perdão por isso para quem ama DRY)
  • Aproveito o processo de escrever um código e entenda que demora para chegar a abstração perfeita. Se você quer levar isso ao próximo nível, aproveite a oportunidade de refatorar para ensinar aos seus colegas sobre o que você está trabalhando.

O que achou? Estou curioso pra saber o que você pensou sobre e ficaria feliz de conversar sobre!

E caso você não tenha conferido ainda, escrevi um artigo muito legal sobre o meu 2020 😉

FIN

Gostou? Compartilhe! 🙌