Neste post
- Como se chega em quinze mil linhas
- O que efetivamente custou
- Doeu: encontrar coisa
- Doeu: o editor
- Doeu: mudança com raio grande
- Não doeu tanto: performance
- Não doeu: publicar
- Onde a linha realmente fica
- O que a gente faz agora
- O que a gente faz diferente em projeto novo
- O que isso diz sobre estúdio pequeno
- Resumo
O Nebulux é um app de tarefas e recompensas com tema espacial: tarefas, carteira com saque, ranking, sistema de indicação, conquistas e painel administrativo.
Ele está publicado, funciona e é usado.
O main.dart dele tem 15.248 linhas.
Este post não é confissão nem defesa. É a análise de como isso acontece, o que efetivamente custou, e qual é o critério que a gente passou a usar.
Como se chega em quinze mil linhas
Ninguém decide isso. É importante começar por aí, porque a explicação mais comum — desleixo — é a menos útil.
O mecanismo é econômico. Em qualquer momento da vida daquele arquivo, a pergunta que aparece é sempre a mesma:
Eu crio um arquivo novo para essas 80 linhas, ou coloco aqui embaixo?
E a resposta honesta, avaliada isoladamente, é coloca aqui embaixo. Criar arquivo custa: importação, decidir nome, decidir pasta, expor o que precisa ser compartilhado. Colar no fim custa zero.
Cada decisão individual está certa. A soma está errada. É dívida técnica no sentido literal do termo: cada parcela é confortável, e o principal cresce sozinho.
O que efetivamente custou
Vale separar o que doeu do que só parecia feio.
Doeu: encontrar coisa
Busca textual funciona; navegação estrutural não. Não dá para "abrir o arquivo do ranking" porque não existe arquivo do ranking. Existe a região do ranking, e achar a fronteira dela é trabalho manual toda vez.
O custo real aparece quando você volta depois de meses. A memória de onde as coisas estavam é o índice — e ela expira.
Doeu: o editor
Análise estática, autocompletar e formatação ficam visivelmente mais lentos num arquivo desse tamanho. Não é catastrófico, é atrito constante: meio segundo em cada operação, o dia inteiro.
Doeu: mudança com raio grande
Alterar algo compartilhado — uma constante de cor, um formato de moeda — vira busca e substituição num arquivo onde o mesmo nome aparece em contextos diferentes. Sem fronteira de módulo, não há limite natural para o alcance de uma mudança.
Não doeu tanto: performance
Tamanho de arquivo não afeta o app rodando. Dart compila; o binário não sabe em quantos arquivos você escreveu. Isso é importante dizer porque a intuição de quem vê o número é "deve estar lento", e não está.
Não doeu: publicar
O aplicativo passou nas revisões das lojas, atualiza normalmente e não tem comportamento diferente por causa disso.
O sintoma de monolito não é o app funcionando pior. É você trabalhando pior. Por isso ele demora tanto a ser tratado: não aparece em métrica de produto, só em velocidade de quem mexe.
Onde a linha realmente fica
Depois desta experiência, o critério que a gente passou a usar não é número de linhas. É este:
O arquivo cresceu até o ponto em que duas pessoas não conseguem trabalhar nele ao mesmo tempo?
Enquanto o autor é um só, um arquivo grande é principalmente incômodo. No momento em que entra uma segunda pessoa, ele vira gargalo — todo trabalho passa pelo mesmo arquivo, todo commit conflita, e o custo de coordenação supera qualquer conveniência.
O segundo critério, complementar:
Você consegue explicar onde uma funcionalidade mora sem abrir o editor?
Se a resposta é não, a estrutura parou de comunicar. E estrutura que não comunica é documentação que apodreceu.
O que a gente faz agora
Não foi um mutirão de refatoração, e essa é a parte importante do relato. Reescrever um app publicado que funciona é risco sem receita — o usuário não percebe nada e a chance de regressão é real.
A regra adotada foi outra: extrair na hora de mexer.
precisa alterar o ranking?
-> extrai o ranking para um arquivo proprio
-> confere que continua igual
-> so entao faz a alteracao pedida
Três propriedades boas disso:
- 1. O custo da extração é pago pelo trabalho que já ia acontecer.
- 2. O que nunca muda nunca é extraído — e tudo bem, porque não incomoda.
- 3. Cada extração é pequena o bastante para ser verificada de verdade.
O arquivo encolhe pelo uso. Não vira zero, e não precisa.
O que a gente faz diferente em projeto novo
Uma regra só, e ela é tosca de propósito para ser seguida sem discussão:
Tela nova nasce em arquivo próprio, mesmo com trinta linhas.
O custo é uma importação. O benefício é nunca ter a conversa "onde eu coloco isso" — porque a resposta já está decidida.
E uma segunda, que evita metade dos monolitos que já vimos: estado e apresentação em arquivos separados desde o primeiro dia. A fusão dos dois é o que faz o arquivo crescer nas duas direções ao mesmo tempo.
O que isso diz sobre estúdio pequeno
Vale um parágrafo de contexto, porque a conclusão muda com o tamanho da equipe.
Numa operação com muitas pessoas, esse arquivo teria sido barrado na revisão. E com razão: o custo de coordenação seria imediato.
Numa operação de uma ou duas pessoas, o cálculo é diferente. O aplicativo no ar gerando resultado vale mais que a arquitetura correta de um aplicativo que não saiu. O monolito do Nebulux não é a melhor decisão técnica — é a decisão que permitiu ele existir.
O erro não foi escrever assim no começo. Foi não ter definido, no começo, o gatilho que dispararia a mudança.
Resumo
- Monolito não é decisão. É acúmulo de decisões locais corretas.
- O que dói é navegação, atrito de editor e raio de mudança. Performance não é
afetada.
- O critério útil não é número de linhas: é se duas pessoas conseguem trabalhar
ao mesmo tempo, e se dá para dizer onde algo mora sem abrir o editor.
- Refatoração grande em app publicado é risco sem receita. Extrair na hora de
mexer paga o custo com trabalho que já ia acontecer.
- Em projeto novo: tela nova em arquivo próprio, sempre; estado separado de
apresentação desde o primeiro dia.
Perguntas frequentes
Vocês recomendam fazer isso?
Não como padrão. Recomendamos entender por que aconteceu, porque o mecanismo é o mesmo que produz monolito em qualquer base: cada adição isolada é barata, e ninguém decide 'vamos ter quinze mil linhas'. A decisão nunca é tomada; ela é acumulada.
Por que não refatorar de uma vez?
Porque refatoração grande em app publicado é risco sem receita. O caminho que usamos é extrair na hora de mexer: toda vez que uma parte precisa mudar, ela sai antes de mudar. O arquivo encolhe pelo uso, não por mutirão.
Ferramenta de análise não reclamou antes?
Reclamou, e o aviso foi ignorado porque não havia sintoma. Métrica de complexidade sem dor associada é fácil de ignorar — o sintoma só aparece quando alguém novo tenta mexer, ou quando você volta depois de três meses.