“Fixar com pregos” e “hardcodificar” são termos jargão que significam a fixação rígida de valores diretamente no código do programa, em vez de colocá-los em configurações ou definições. Hardcode é um dos antipadrões mais conhecidos no desenvolvimento, pois reduz a flexibilidade e a reutilização do código. Segundo o Refactoring Guru, o hardcode dificulta os testes, a manutenção e a adaptação da aplicação a diferentes ambientes. O uso consciente de constantes em vez de hardcode é um sinal de arquitetura madura.
Principais pontos
Hardcodificar (fixar com pregos) — incorporar um valor específico no código do programa de modo que, para alterá-lo, seja necessário editar o código fonte e recompilar a aplicação. A metáfora “fixar com pregos” reflete precisamente a essência: o valor está fixado permanentemente, e só pode ser removido do código com esforço.
Exemplo de hardcode — uma URL de servidor escrita como string diretamente no corpo de uma função. Se o servidor mudar para outro endereço, o desenvolvedor precisa encontrar a string no código, alterá-la, recompilar a aplicação e lançar uma nova versão. Em uma aplicação com arquitetura adequada, essa URL estaria em um arquivo de configuração, variável de ambiente ou serviço de configuração.
O termo “fixar com pregos” é mais carregado emocionalmente: enfatiza que o valor foi inseridos permanentemente, sem possibilidade de substituição rápida. No ambiente de língua russa, ambas as expressões são usadas como sinônimos completos com conotação negativa. Às vezes, o hardcode é ironicamente chamado de “constante extraída para uma constante separada de uma constante”.
Hardcode — um antipadrão porque viola os princípios de manutenibilidade, testabilidade e extensibilidade do código. Em código onde os valores estão “fixados com pregos”, qualquer alteração de ambiente, design ou lógica exige busca e substituição manuais nos fontes. Isso aumenta o risco de erros e retarda o desenvolvimento.
Vamos considerar as consequências específicas do hardcode usando um aplicativo móvel típico como exemplo. Se a margem de todos os botões for definida por um número no código, e não por um recurso — uma alteração de design exigirá encontrar todas as ocorrências e substituí-las. Se a URL do endpoint estiver fixada rigidamente — a alternância entre ambientes (dev, stage, prod) é impossível sem recompilação.
| Consequência | Descrição | Nível de criticidade |
|---|---|---|
| Dificuldade de manutenção | Alteração exige busca em todo o código | Alto |
| Erros ao copiar | Nem todas as ocorrências são encontradas e substituídas | Alto |
| Impossibilidade de testar | Não é possível substituir dados de teste | Médio |
| Problemas de localização | Textos no código não são traduzidos | Médio |
| Complexidade de code-review | Revisor precisa lembrar todos os contextos | Baixo |
Uma função que usa números mágicos e strings fixadas — o exemplo clássico de hardcode. Em um mês, o autor não se lembrará do que significam 18, 0.07 e 2.5. Em um ano — ninguém na equipe ousará alterar esses números, com medo de quebrar a lógica. Extrair valores para constantes nomeadas torna o código autodocumentado.
// Ruim: números mágicos e strings
fun calculatePrice(base: Double): Double {
val tax = base * 0.07
val tip = base * 0.15
val discount = if (base > 100) 10 else 0
return base + tax + tip - discount
}
Uma URL de banco de dados hardcodificada não permitirá executar testes em um banco de dados local in-memory. O desenvolvedor terá que iniciar um servidor completo ou editar o código antes dos testes. Extrair a configuração do código resolve o problema: os testes usam parâmetros de teste, a produção usa parâmetros reais, e o código permanece inalterado.
Hardcode é um antipadrão, mas existem exceções legítimas onde um valor fixado não é apenas aceitável, mas também preferível. O limite segue o eixo de mutabilidade: se o valor nunca ou quase nunca muda dentro do ciclo de vida da aplicação, ele pode ser hardcodificado. Se houver potencial de mudança — coloque na configuração.
Constantes matemáticas e físicas — Pi, aceleração da gravidade, número de milissegundos em um segundo — são seguras para hardcode. Elas são definidas pela natureza ou por padrões e não mudarão. Tamanhos de arrays constantes definidos por especificação também podem ser fixados, mas com um comentário sobre a origem do número.
O número de milissegundos em um segundo é uma constante estável definida pelo padrão de tempo. Não há sentido em colocá-la em um config, porque ela nunca mudará. No entanto, mesmo essas constantes é melhor declarar com um nome claro, para que o código não contenha “números mágicos”: em vez de 1000, escreva MILLISECONDS_IN_SECOND.
// Hardcode justificado: constantes estáveis
private const val MILLIS_IN_SECOND = 1000
private const val LOGIN_TIMEOUT_SECONDS = 30
fun formatDuration(ms: Long): String {
val seconds = ms / MILLIS_IN_SECOND
return "${seconds} sec."
}
Existem várias maneiras comprovadas de evitar hardcode, cada uma adequada para seu tipo de valor. A escolha da alternativa depende de com que frequência o valor muda e quem o altera: desenvolvedor, devops ou usuário final.
Para URLs de servidores, chaves de API e feature flags, use arquivos de configuração nos formatos JSON, YAML ou TOML. No Android, isso é build.gradle com buildConfigField ou res/values/config.xml. No iOS — Info.plist ou xcconfig. Os configs são compilados junto com a aplicação, mas podem ser diferentes para diferentes esquemas de build.
Para segredos (tokens, senhas) e parâmetros de ambiente, use variáveis de ambiente. Elas não entram no repositório e podem diferir nos servidores dev, stage e prod. No desenvolvimento móvel, as variáveis de ambiente são frequentemente emuladas através de esquemas de build do Xcode ou build flavors no Gradle.
Strings, cores, tamanhos, imagens devem ser colocados em arquivos de recurso: strings.xml no Android, Localizable.strings no iOS, arquivos ARB no Flutter. Isso facilita a localização, adaptação a diferentes telas e tema escuro. Alterar uma string nos recursos não exige reescrever o código.
<!-- Android: res/values/strings.xml -->
<resources>
<string name="app_name">MyApp</string>
<string name="api_base_url">https://api.example.com</string>
</resources>
Para serviços e provedores, use Dependency Injection através de Dagger, Hilt ou Koin no Android, Swinject no iOS. Frameworks DI permitem substituir implementações em tempo real — para testes, para diferentes ambientes, para diferentes usuários. Este é o nível mais alto de abstração, onde a “fixação” do valor é substituída por injeção externa.
Refatorar hardcode — o processo de extrair valores fixados para configuração ou recursos. É uma das operações de refatoração mais seguras, se feita metodicamente. A sequência descrita abaixo é adequada para qualquer linguagem e plataforma.
A busca pode ser feita através da IDE (Search in Project) ou script. Procure strings, URLs, literais numéricos, tamanhos, timeouts. Atenção especial — a valores repetidos: se o mesmo número aparece em cinco lugares, é candidato a se tornar constante. Use grep ou a busca integrada do IDEA / Xcode.
Para cada valor encontrado, crie uma constante com um nome significativo. Agrupe constantes por módulos ou classes. O nome deve explicar o que o valor significa, não como é usado: API_TIMEOUT, em vez de TIMEOUT_30. Após a substituição, nenhum número no código deve ficar sem explicação.
// Antes: número mágico 0.4
let cardHeight = screenHeight * 0.4
// Depois: constante nomeada
private let cardHeightRatio: CGFloat = 0.4
let cardHeight = screenHeight * cardHeightRatio
Se o valor pode variar entre builds ou ambientes — coloque-o em um arquivo de configuração ou recursos da aplicação. Para strings, use arquivos de localização. Para URLs — build config ou xcconfig. Para tamanhos — arquivos de recurso (dimens.xml no Android). Verifique se a aplicação compila e funciona corretamente após a extração.
Após a refatoração, escreva um teste que verifique se a configuração é carregada corretamente e os valores correspondem ao esperado. Se no futuro alguém alterar o config, o teste apontará a divergência. Um teste de configuração é uma maneira rápida e confiável de prevenir regressão.
Após extrair para o config, verifique se todos os lugares que usavam o valor antigo referenciam a fonte única. Remova código comentado e constantes antigas que não são mais usadas. Finalize a refatoração com um commit cuja mensagem descreva quais valores e para onde foram extraídos.
Perguntas frequentes
Hardcodificar — escrever um valor diretamente no código fonte em vez de colocá-lo em configuração ou recursos. Isso torna o código menos flexível e mais difícil de manter.
Hardcode dificulta a alteração do comportamento da aplicação, atrapalha os testes, cria duplicação e aumenta o risco de erros ao copiar. Alterar um valor hardcodificado exige recompilação e novo lançamento da aplicação.
Aceitável para constantes matemáticas, valores estáveis que não mudam no ciclo de vida da aplicação e para protótipos temporários. Em produção, até constantes devem ser extraídas para variáveis nomeadas.
Encontre todos os números mágicos através de pesquisa, substitua-os por constantes nomeadas ou coloque em um arquivo de configuração. Escreva um teste que verifique o carregamento da configuração. Remova duplicatas e faça um commit com a descrição das alterações.
Constante — um valor nomeado no código, disponível para alteração em um único lugar. Hardcode — valores sem nome espalhados pelo código. Boa prática: sempre usar constantes nomeadas com nomes significativos.
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