code smells
code smells (ou cheiro de código) são características ou padrões no código fonte que indicam problemas mais profundos na estruturação do software. Embora os code smells não sejam bugs — pois nem sempre causam falhas no programa —, muitas vezes sinalizam questões que dificultam a manutenção, compreensão ou expansão do código, e podem levar a defeitos ou ineficiências no futuro[1][2][3].
O conceito foi popularizado por Kent Beck e Martin Fowler nos anos 1990 e formalizado no livro Refactoring: Improving the Design of Existing Code de Fowler, publicado em 1999[1:1][4].
Pontos-chave sobre code smells
- Eles sugerem práticas de programação deficientes, como má modularização, complexidade excessiva ou violações aos princípios orientados a objetos[5][3:1].
- Os code smells tendem a acumular-se ao longo do tempo à medida que o software evolui e a manutenção é negligenciada[5:1].
- Tipos comuns de code smells incluem:
- Bloaters: Classes ou métodos muito grandes que lidam com muitas responsabilidades ou se tornaram excessivamente volumosos[5:2][1:2].
Violações (ou Dirties) são códigos cujas intenções originais foram violadas, mas não explicitamente ruins. Ex: usar variáveis locais para armazenar dados que deveriam ser de uma classe. - Violações: Mesmo que acima
- Código duplicado: Ocorrência repetida do mesmo ou código semelhante, prejudicando a manutenção[2:1][3:2].
- Métodos longos ou listas de parâmetros excessivas: Funções fazendo mais do que deveriam ou com muitos parâmetros, reduzindo a legibilidade e reutilização[3:3].
- Violação de Single Responsibility Principle (SRP): Uma classe ou função tem mais de uma responsabilidade.
- Shotgun surgery: Quando uma única alteração requer modificações em múltiplos lugares[5:3][2:2].
- Data clumps: Agrupamentos repetitivos de itens de dados, sugerindo má abstração[2:3][3:4].
- Abusos da orientação a objetos: Uso incorreto de conceitos OO como herança e encapsulamento[5:4][3:5].
- Código morto (Dead code): Código não usado ou inalcançável que polui o repositório[3:6].
- Bloaters: Classes ou métodos muito grandes que lidam com muitas responsabilidades ou se tornaram excessivamente volumosos[5:2][1:2].
- Os code smells impedem mudanças futuras e aumentam os riscos e custos da evolução do software[5:5].
- Identificar code smells precocemente ajuda a prevenir acúmulo de dívida técnica (technical debt) e degradação sistêmica[6].
Tratamento dos code smells
- A maneira principal para lidar com os code smells é através de refatoração — reestruturar o código sem mudar seu comportamento externo, visando melhorar a estrutura e legibilidade[3:7].
- Refatoração pode incluir quebrar métodos grandes, simplificar chamadas de função e abstrair código duplicado[3:8].
- Refatorar regularmente ajuda a manter o código saudável[3:9].
- Ferramentas automatizadas como SonarQube, Visual Studio Code, etc., podem detectar code smells e auxiliar na correção[3:10][7].
Em resumo, os code smells funcionam como alertas no desenvolvimento de software, indicando áreas onde o código precisa ser limpo e melhorado para evitar problemas futuros, aumentar a manutenibilidade e apoiar uma evolução sustentável do sistema[3:11][7:1].
Prompts para identificar code smells
-
"Analise este trecho de código e identifique possíveis code smells presentes."
-
"Quais code smells você pode encontrar neste arquivo/função/classe?"
-
"Detecte code smells comuns em projetos Java/Python/JavaScript e explique por quê."
-
"Liste os principais code smells que podem surgir ao longo do tempo em um sistema legado."
-
"Dê exemplos de code smells típicos em programação orientada a objetos."
Prompts para explicar conceitos de code smells
-
"Explique o que é o code smell 'Long Method' e por que ele é problemático."
-
"Como o code smell 'Duplicated Code' pode impactar a manutenção do software?"
-
"Qual a diferença entre code smells e bugs?"
-
"Por que o code smell 'Shotgun Surgery' deve ser evitado?"
-
"Como identificar o code smell 'Data Clumps' e qual é a melhor forma de refatorar?"
Prompts para sugerir refatorações baseadas em code smells
-
"Mostre como refatorar um método longo para torná-lo mais legível e modular."
-
"Dê exemplos de refatoração para eliminar código duplicado em um projeto."
-
"Quais técnicas de refatoração são recomendadas para resolver o code smell 'Bloaters'?"
-
"Como refatorar um código com muitos parâmetros para métodos?"
-
"Sugira passos para melhorar um código que sofre de 'Shotgun Surgery'."
Exemplos práticos
Aqui estão exemplos práticos para cada um dos prompts sugeridos anteriormente sobre code smells, com trechos de código ilustrativos e explicações:
1. Identificando code smells
Prompt: “Analise este trecho de código e identifique possíveis code smells presentes.”
def processa(funcionario, salario, bonus, horas, horas_extras, deducao, descontos):
result = salario + bonus + (horas_extras * 20) - deducao - descontos
print(f"Funcionario: {funcionario}")
print(f"Salario final: {result}")
log_funcionario(funcionario)
Code smells presentes:
- Long Parameter List (lista de parâmetros longa)
- Data Clumps (muitos dados são passados juntos repetidamente)
- Baixa coesão de responsabilidades
2. Explicando code smells
Prompt: “Explique o que é o code smell 'Long Method' e por que ele é problemático.”
Exemplo:
public void processOrder(Order order) {
calculateDiscounts(order);
updateInventory(order);
printReceipt(order);
sendOrderConfirmationEmail(order);
logOrder(order);
// ...muitos outros passos aqui
}
Problema: O método faz muita coisa, dificultando testes e manutenção.
3. Refatorando code smells
Prompt: “Mostre como refatorar um método longo para torná-lo mais legível e modular.”
Antes:
function salvarPedido(pedido) {
validarPedido(pedido);
calcularFrete(pedido);
aplicarDesconto(pedido);
atualizarEstoque(pedido);
enviarConfirmacao(pedido);
}
Depois (dividido em métodos menores):
function salvarPedido(pedido) {
validarEReservar(pedido);
aplicarPreco(pedido);
finalizarPedido(pedido);
}
function validarEReservar(pedido) {
validarPedido(pedido);
atualizarEstoque(pedido);
}
function aplicarPreco(pedido) {
calcularFrete(pedido);
aplicarDesconto(pedido);
}
function finalizarPedido(pedido) {
enviarConfirmacao(pedido);
}
4. Code smell “Duplicated Code” e como remover
Antes:
def calcula_total_com_desconto(produtos):
total = sum(produtos)
if total > 100:
total = total * 0.9
return total
def calcula_total_sem_desconto(produtos):
total = sum(produtos)
return total
Depois (removendo duplicidade):
def calcula_total(produtos, aplica_desconto=False):
total = sum(produtos)
if aplica_desconto and total > 100:
total = total * 0.9
return total
5. Refatorando muitos parâmetros (“Long Parameter List”)
Antes:
public void criarCadastro(String nome, String sobrenome, String endereco, String telefone, String email, String rg, String cpf) { /* ... */ }
Depois (usando objeto):
public void criarCadastro(Pessoa pessoa) { /* ... */ }
Se quiser um exemplo aprofundado sobre algum dos code smells mencionados ou ver exemplos em outra linguagem de programação, é só pedir!
Referências
https://coodesh.com/blog/dicionario/o-que-e-code-smell/ ↩︎ ↩︎ ↩︎
https://www.techtarget.com/searchsoftwarequality/tip/Understanding-code-smells-and-how-refactoring-can-help ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
https://refactoring.guru/pt-br/refactoring/smells ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
https://www.dio.me/articles/entendendo-code-smells-e-a-importancia-de-identifica-los-precocemente ↩︎