Código ruim é um termo informal para código fonte de baixa qualidade: ilegível, mal estruturado e difícil de manter. De acordo com um relatório da Stripe (2022), os desenvolvedores gastam até 40% do seu tempo de trabalho lendo e entendendo código mal escrito. Na comunidade de língua russa, o termo é tão difundido que existe um site especializado govnokod.ru onde os desenvolvedores publicam exemplos de casos particularmente marcantes.
Principais pontos
Código ruim é uma caracterização subjetiva mas geralmente aceita de código que não atende aos padrões mínimos de qualidade. Robert Martin em seu livro Código limpo (2008) define código ruim como aquele que “impede de entender o que faz”. Código ruim pode ser sintaticamente correto e até funcionar, mas sua manutenção se torna um pesadelo para a equipe.
O termo código ruim é difundido precisamente na comunidade de língua russa. Em inglês, termos mais formais são usados: spaghetti code, dirty code, technical debt code. No entanto, a carga emocional de “código ruim” transmite com mais precisão a atitude dos desenvolvedores em relação a esse código — uma mistura de irritação, nojo e ofensa profissional.
De acordo com um estudo da McKinsey (2023), empresas com altos níveis de dívida técnica — e o código ruim é seu principal componente — gastam 20–40% mais recursos no desenvolvimento de novos recursos. A qualidade do código afeta diretamente as métricas de negócios, e isso não é uma metáfora, mas um fato confirmado.
Não existem métricas objetivas, mas há critérios práticos: se um desenvolvedor leva mais de 5 minutos para entender uma função de 20 linhas — é código ruim. Se alterar uma linha quebra três módulos não relacionados — é código ruim. Se o código não pode ser coberto por testes sem uma reescrita completa — é código ruim.
Copiar e colar (copy-paste programming) é um dos sinais mais óbvios e fáceis de detectar. Quando o mesmo bloco de código se repete em vários lugares com mudanças mínimas, não é só código ruim — é uma fonte de futuros erros. Corrigir em um lugar e esquecer em outro é uma situação típica.
Nomes de variáveis sem significado são um clássico. Variáveis com nomes como `a`, `b`, `x`, `data`, `temp`, `tmp`, `result`, `list`, `obj` não carregam nenhuma informação sobre seu propósito. O leitor do código precisa analisar toda a função para entender o que a variável contém. Robert Martin chama isso de “uma mentira no nome” — o nome promete informação mas não a entrega.
Aninhamento profundo — quando condicionais, loops e tratamento de erros criam uma estrutura com 5+ níveis de indentação. Esse código é impossível de ler sem rolagem horizontal ou acompanhamento mental de todos os níveis. Isso é um caminho direto para erros: operadores lógicos são facilmente confundidos e colchetes de fechamento são esquecidos.
| Sinal | Exemplo de código ruim | Código limpo |
|---|---|---|
| Copiar e colar | Um bloco copiado 5 vezes | Extraído em uma função |
| Nomes | `var a = getData()` | `var userList = getData()` |
| Aninhamento | 6 níveis de if/for | 2–3 níveis com return early |
| Funções | Função de 300 linhas | Dividida em 3–5 métodos |
| Comentários | `i++ // incrementar i` | Código autoexplicativo sem comentários |
Código morto (dead code) — funções, variáveis, classes que não são usadas em lugar nenhum. Isso aumenta o volume de código, distrai o desenvolvedor e cria uma falsa impressão sobre as capacidades do sistema. Números mágicos — números sem contexto. Classes Deus (God classes) — classes que fazem tudo ao mesmo tempo, violando o princípio da responsabilidade única (SOLID: S).
A falta de tempo é a razão mais comum. Quando os prazos apertam, os desenvolvedores sacrificam a qualidade pela velocidade. Taticamente, isso pode ser justificado, mas estrategicamente — é acúmulo de dívida técnica. O problema é que o código ruim “temporário” raramente é revisitado para correção.
A falta de revisão de código é a segunda razão mais importante. Quando o código é escrito sozinho sem revisão de colegas, os maus padrões se enraízam e se multiplicam. A revisão de código não é apenas controle de qualidade, mas também transferência de conhecimento dentro da equipe. Projetos sem revisão inevitavelmente degeneram em código ruim.
A baixa qualificação do desenvolvedor ou a falta de mentoria. Desenvolvedores juniores deixados sem supervisão escrevem código ruim naturalmente — faz parte do processo de aprendizado. O problema surge quando esse código vai para produção sem revisão e refatoração.
Em equipes onde “funciona e está bom” é o lema, o código ruim prospera. A ausência de padrões de codificação, requisitos de teste e processos de revisão cria um ambiente onde a qualidade do código não importa para ninguém. Esses projetos rapidamente se tornam “legado” — código que todos temem tocar.
A principal consequência do código ruim é a desaceleração do desenvolvimento. O paradoxo do código ruim é que ele permite escrever rapidamente a primeira versão, mas cada correção posterior leva cada vez mais tempo. O gráfico da velocidade de desenvolvimento versus qualidade do código é exponencial — após certo limite, adicionar novos recursos se torna praticamente impossível.
A rotatividade de pessoal é uma consequência indireta mas grave. Desenvolvedores, especialmente os experientes, não querem trabalhar com código ruim. De acordo com a Pesquisa de Desenvolvedores Stack Overflow 2024, 47% dos desenvolvedores consideram a qualidade da base de código um dos principais fatores ao escolher um local de trabalho. Projetos com código ruim perdem seus melhores funcionários.
A segurança é outra vítima do código ruim. Código mal escrito contém mais vulnerabilidades: exceções não tratadas, injeções SQL, XSS, vazamentos de memória. Código de qualidade com testes unitários e revisão de código detecta a maioria desses problemas antes da produção.
SonarQube e ferramentas similares podem estimar a dívida técnica em horas-homem ou dias. Por exemplo, 500 avisos de copiar e colar, 200 de números mágicos e 50 de aninhamento profundo dão uma estimativa de 30 dias de dívida técnica. Esses números podem e devem ser mostrados à gerência para justificar a refatoração.
O princípio DRY (Don’t Repeat Yourself) é a primeira coisa a implementar. Cada fragmento de lógica deve existir em um único lugar. Em vez de copiar e colar — extraia o código repetido em uma função, classe ou módulo separado. Em vez de números mágicos — constantes nomeadas. Em vez de funções longas — várias pequenas.
O princípio KISS (Keep It Simple, Stupid) protege contra complexidade excessiva. Se uma tarefa pode ser resolvida em 10 linhas — não escreva 50. Se um loop é mais simples que um stream — use um loop. Se uma função comum é mais clara que um decorador — escreva uma função. Simplicidade é a principal qualidade do código sustentável.
A regra Boy Scout — “deixe o código melhor do que você o encontrou”. Mesmo pequenas melhorias a cada edição gradualmente transformam código ruim em código decente. Renomear uma variável, dividir uma função grande, adicionar um teste — qualquer melhoria importa.
// código ruim — copiar e colar, números mágicos, nomes pobres
function calc(a, b, c) {
let x = a * 0.85;
if (b > 1000) { x = x * 0.9; }
let y = c * 0.85;
if (b > 1000) { y = y * 0.9; }
return x + y;
}
// código limpo — nomes claros, DRY, constantes
const DISCOUNT_RATE = 0.85;
const BULK_THRESHOLD = 1000;
const BULK_DISCOUNT = 0.9;
function applyDiscount(amount, quantity) {
let price = amount * DISCOUNT_RATE;
if (quantity > BULK_THRESHOLD) {
price = price * BULK_DISCOUNT;
}
return price;
}
function calculateTotal(items, quantity) {
return items.reduce((sum, item) => {
return sum + applyDiscount(item, quantity);
}, 0);
}
Vamos considerar um exemplo típico em Python. A função processa pedidos mas o faz mal: 80 linhas, aninhamento profundo, números mágicos, duplicação. Após a refatoração, o código se torna legível, testável e sustentável.
# código ruim — uma única função faz tudo
def process_order(order):
if order.get("type") == "premium":
if order["amount"] > 100:
discount = 0.8
else:
discount = 0.9
else:
discount = 1.0
total = order["amount"] * discount
return total
# código limpo — funções e constantes extraídas
class OrderProcessor:
PREMIUM_DISCOUNT_HIGH = 0.8
PREMIUM_DISCOUNT_LOW = 0.9
PREMIUM_THRESHOLD = 100
def get_discount(self, order):
if order.type == "premium" and order.amount > self.PREMIUM_THRESHOLD:
return self.PREMIUM_DISCOUNT_HIGH
return self.PREMIUM_DISCOUNT_LOW
def calculate_total(self, order):
return order.amount * self.get_discount(order)
Uma boa função faz uma coisa e a faz bem. Se uma função faz três coisas diferentes — divida-a. Se uma função tem mais de 20 linhas — provavelmente pode ser dividida. Se uma função tem mais de dois níveis de indentação — precisa de refatoração.
Analisadores estáticos de código são a primeira linha de defesa contra código ruim. ESLint (JavaScript), Pylint (Python), SonarQube (multilinguagem), Checkstyle (Java) detectam automaticamente copiar e colar, números mágicos, blocos catch vazios, funções excessivamente longas e centenas de outros antipadrões.
Padrões de código e formatadores são o segundo nível de proteção. Prettier, Black, gofmt formatam o código automaticamente, eliminando problemas com espaços, indentação e colchetes. Um estilo consistente na equipe torna o código legível independentemente de quem o escreveu. Discussões sobre formatação devem ser automatizadas.
Revisão de código é o terceiro e mais importante nível. Nenhum analisador pode substituir uma pessoa que percebe que a arquitetura da solução está errada ou que o desenvolvedor escolheu a abordagem errada. Revisão eficaz requer tempo, mas se paga reduzindo significativamente a quantidade de código ruim.
Perguntas frequentes
Extremamente raro. Em prototipação ou hackathons, a velocidade importa mais que a qualidade, mas esse código deve ser marcado como temporário e não deve ir para produção sem refatoração. Em produção, não há desculpa para código ruim — qualquer tempo economizado agora se transformará em perdas multiplicadas no futuro.
O código de iniciante é inexperiente mas frequentemente sincero, que melhora com o crescimento das habilidades. Código ruim é uma negligência consciente ou indiferente da qualidade. Um iniciante pode escrever código subótimo mas legível. Código ruim, por outro lado, é fundamentalmente ilegível — seu autor não se importa se outros o entendem.
Reescrever é o último recurso. A refatoração gradual é mais segura: você isola um módulo, cobre com testes, reescreve peça por peça. A reescrita completa é arriscada — você pode perder a lógica de negócio acumulada no código antigo, incluindo o tratamento de casos extremos que ninguém documentou.
Use métricas: SonarQube mostrará a dívida técnica em horas. Mostre quanto tempo é gasto com erros no código antigo. Compare a velocidade de desenvolvimento de novos recursos nas partes “limpa” e “suja” do projeto. Traduza para a linguagem de negócios: tempo é dinheiro, e código ruim custa dinheiro.
Código limpo de Robert Martin (2008) é a bíblia da programa ção de qualidade. Ele cobre princípios de nomenclatura, formatação, tratamento de erros e testes. Adicionalmente: Código completo de Steve McConnell, Refatoração de Martin Fowler, Padrões de projeto do Gang of Four. Todo desenvolvedor deveria ler esses livros.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também