Uma expressão que para você pode soar estranha, mas na área de desenvolvimento de software é muito conhecida. Vamos entender melhor neste artigo o que é um Code Smell, ao que o termo se refere e dicas para aumentar a qualidade de nosso código. Não vamos ter exemplos neste artigo (em código), mas já estou preparando um conteúdo bem legal com exemplos 😃. Um ponto a destacar é que esse artigo é voltado para quem nunca teve tempo de entender melhor a expressão. Então vamos lá!
Um código que cheira?
Se você for no Google Tradutor agora e realizar a tradução das palavras pode ficar mais confuso ainda. Afinal o que é um código que cheira? A palavra smell refere-se a cheiro e nós sabemos que algo que tem um odor é perceptível. Então quer dizer que é um odor ruim? Não exatamente, mas podemos dizer que esse código pode causar algum incômodo pela maneira que foi escrito. Talvez por faltar coesão, por ter linhas desnecessárias ou por código redundante, além repetição de lógica no código.
Então quer dizer que podemos considerar code smell um código que apresenta bugs ou falhas nos testes? Também não, o código pode até funcionar 100% sem causar efeitos colaterais na aplicação ou na experiência do usuário final, além disso pode passar nos testes. Na situação atual, o projeto por estar no inicio pode até ir para produção e funcionar perfeitamente. O termo se refere a um código mal escrito, que não foi planejado, que não foi pensado com calma desde os fundamentos e levando em consideração as boas práticas. E o que um código desse tipo causa a longo prazo? Uma alta taxa de manutenção, um risco enorme que esse software apresente bugs no futuro, seja estressante de entender e faça a equipe perder tempo para incluir novas funcionalidades no sistema .
Além disso um code smell é aquele código que quando for alterado vai exigir mudanças em outras partes do código, o que causa um efeito de propagação, ou seja, podemos ter muitas classes e métodos que irão ser afetados por simples mudanças. Isso torna cansativo para o desenvolvedor que está trabalhando naquele código e uma tarefa que pode levar dias! Percebe-se então que esse código é rígido.
Um código mal feito é algo tão sério e prejudicial para o bom andamento de um projeto de software, que temos tipos de code smell que já foram identificados. Vamos abordar rapidamente cada um deles.
Bloaters (Código Inflado ou inchado)
O termo bloater, refere-se a palavra inchado, inflado. Quando pensamos em código podemos visualizar um que está muito extenso, assumindo várias responsabilidades e até mesmo verificando ou realizando coisas que poderiam ser separadas. Pense em um método que cria, realiza o update e deleta, e ainda verifica se irá ser necessário ou não enviar um e-mail para o usuário final. Por que esse método, ou classe, tem que assumir tantas responsabilidades? Será que não faltou critério do desenvolvedor ao construir? Ou pense em uma classe que tenha 837 linhas! Já imaginou quantas responsabilidades desnecessárias essa classe pode estar assumindo? Agora imagine as outras classes dessa aplicação! Isso é algo preocupante para o bom andamento do projeto.
Object-Orientation Abusers (Violação a orientação a objetos)
Na POO (Programação orientada a objetos), temos 4 pilares que são:
Abstração
Herança
Polimorfismo
Encapsulamento
Não vamos entrar afundo nestes pilares, mas o que você precisa saber é que quando o desenvolvedor aplica de maneira incorreta os fundamentos, isso vai gerar problemas em um código. Veja um exemplo:
Imagine que contratou uma construtora (empresa), para construir sua futura casa. Mas na entrega percebe que ela teve os fundamentos e estruturas mal feitos, com visíveis rachaduras nas paredes dos quartos e outros cômodos da casa. Você com certeza não se sentiria seguro em dormir nessa casa, não concorda? Nem mesmo pensaria em contratar novamente as pessoas que planejaram a sua arquitetura. Você fica até decepcionado pois terá que derrubar tudo e começar novamente. E isso custa tempo e dinheiro. Mas como isso é visível em código?
Basta visualizar um código com muitos if ou switchs gigantes e difíceis de entender. Imagine um método que contém uma sequência de if/switch, que realizam verificações que ao mesmo tempo nem tem relação com a classe onde se encontram. Um código escrito dessa forma precisa ser realocado em classes e métodos distintos, mas isso envolve rearranjar os blocos de código. Isso é uma tarefa que exige muita atenção e tempo. Uma solução é separar as responsabilidades de classes e métodos.
Ou podemos ter classes que tem um relacionamento de herança. E essas classes herdam de outras que não fazem sentido e no final sua aplicação acaba tendo um forte acoplamento! Isso gera a necessidade de refatorar muitas classes, pois a cada inclusão de uma nova feature na aplicação as outras classes que estão herdando são afetadas, em casos extremos é mais viável começar o projeto do zero, algo que não seria necessário se a equipe (desenvolvedor) que iniciou o projeto tivesse levado em consideração tudo isso que já abordamos.
Dispensables (Código Dispensável)
Podemos considerar um code smell, códigos que tem linhas desnecessárias, duplicados, comentários que não fazem sentido estar ali ou longos demais. Imagine que foi decidido pelo cliente que uma funcionalidade não fará mais parte do Software, você acha que faz sentido deixar aquele código ali? Sabemos que o cliente é uma caixinha de surpresa, mas no momento não faz sentido nenhum estar ali aquele método, bloco de código ou até mesmo classe que cuidava daquela responsabilidade! O certo seria remover o código em vez de deixar ele comentado em sua classe ou método. Import's de uma classe especifica que nunca são usados ou nomes de variáveis que ficam perdidas nas classes também se encaixam nesse tipo.
Couplers (Acopladores)
Não vou entrar em detalhes nos fundamentos da programação orientada a objeto neste artigo. Mas quando falamos de acoplamento estamos nos referindo o quanto a classe B depende ou conhece os comportamentos e propriedades da classe A ou de outras, para que ela realize seu objetivo. Esse code smell é bem específico pois é preciso analisar bem as classes da aplicação e verificar se a herança foi corretamente aplicada ou não. Existem relacionamentos entre classes que são desnecessários e que surgem pela falta de separação de responsabilidade.
Change Preventers (Inibidores de modificação)
É um código difícil de ser alterado em um ponto específico de uma aplicação, pois se alterar em determinado classe ou método também será necessário alterar em vários outros. É aquele código que aparenta ser até simples de alterar, mas quando você realiza o build da aplicação, aparecem vários erros no console indicando que temos que alterar outras classes que nem sequer abrimos na IDE. Alguns falam que é igual a uma dor de cabeça, mas na minha opinião é pior, uma dor de cabeça pode passar rápido, já essas refatorações podem levar muito tempo e talvez seja até preciso refazer a lógica atual (em casos extremos), fora isso você vai encontrando outras classes, ou piores do que a qual você refatorou e no fim parece que você quer desistir da profissão e cogita até mesmo mudar de vida e nome 😂.
Conclusão
Este artigo foi direcionado para estudantes que estão iniciando na área ou para aqueles que acham que seguir os princípios do Clean Code é perda de tempo. Se você deseja evitar Code Smell, é importante entender como aplicar um código limpo quando está desenvolvendo. O objetivo de tudo o que lemos é mostrar o quão importante é trabalhar com responsabilidade quando está desenvolvendo um software, seja ele para uso pessoal ou para uma empresa de pequeno, médio e grande porte! A questão é se você vai aplicar e pesquisar mais afundo esses princípios e padrões. A justificativa de muitos desenvolvedores que não aplicam o código limpo e não evitam o code smell são os prazos curtos, projetos pequenos que ao entendimento deles não terá novas funcionalidades, a empresa onde está não paga bem, entre várias outras justificativas. Mas a questão aqui não é sobre entregar ou não dentro do prazo, ou se seu salário não é justo, mas a questão é: Como seu trabalho vai ser lembrado! Voltamos agora ao exemplo da casa. Você compraria uma casa que tem os alicerces e pilares mal feitos? Não! Nem mesmo contrataria a empresa responsável pela obra. Então com base nisso. Por que não aplica aos poucos as boas práticas e princípios de desenvolvimento de software? Acredite que se você seguir desde o começo as recomendações, irá ter muito mais produtividade!
Portanto, analise bem como vai iniciar seu projeto. Calcule bem o tempo e se programe para desenvolver com a melhor qualidade que puder! Vou deixar ao final do artigo algumas leituras que podem melhorar sua visão de como aplicar um código limpo! Críticas construtivas são bem vindas! Fico por aqui nesse post, até o próximo 😁!
Livros para Estudo e referências:
Código limpo: Habilidades práticas do Agile Software - Robert C. Martin.
O codificador limpo - Robert C. Martin.
Arquitetura limpa: O guia do artesão para estrutura e design de software - Robert C. Martin.
Site: refactoring.guru/pt-br/*.
Refatoração - Aperfeiçoando o Projeto de Código Existente => Livro por Kent Beck e Martin Fowler.
Existem centenas de artigos com conteúdo rico em informação, basta pesquisar por Clean Code e Code Smell.
Site: codesmells.org