Por que dividir um algoritmo em partes
Organize algoritmos extensos em partes com responsabilidades, entradas e resultados claros, preservando o comportamento e facilitando mudanças.

Dividir reduz o que precisa ser entendido de uma vez
Dividir um algoritmo em partes significa agrupar passos relacionados sob responsabilidades claras. Em vez de acompanhar simultaneamente entrada, validação, cálculo, regras especiais e apresentação, o leitor pode compreender um bloco de cada vez e depois observar como eles colaboram.
Essa organização é diferente de decompor um problema. A decomposição identifica os subproblemas necessários para resolver uma necessidade. Aqui partimos de uma solução já compreendida — possivelmente até funcionando — e melhoramos suas fronteiras internas.
Uma boa divisão procura responder:
- qual resultado esta parte produz;
- quais dados ela precisa conhecer;
- quais decisões podem permanecer escondidas dentro dela;
- o que deve continuar igual se sua implementação mudar.
O objetivo não é produzir o maior número de partes. É diminuir a quantidade de contexto necessária para explicar, testar e alterar cada responsabilidade.
Observe quando um algoritmo começa a misturar motivos de mudança
Considere um fechamento de pedido com itens já carregados:
subtotal <- 0
PARA CADA item DO pedido FAÇA
SE item.quantidade <= 0 OU item.preco < 0 ENTÃO
EXIBIR "Pedido inválido"
ENCERRAR
FIM SE
subtotal <- subtotal + item.preco * item.quantidade
FIM PARA
SE cupom = "CLIENTE10" ENTÃO
desconto <- subtotal * 0,10
SENÃO
desconto <- 0
FIM SE
total <- subtotal - desconto
EXIBIR "Subtotal:", subtotal
EXIBIR "Desconto:", desconto
EXIBIR "Total:", total
O algoritmo é curto o bastante para executar, mas reúne pelo menos quatro responsabilidades:
- validar itens;
- calcular o subtotal;
- decidir o desconto;
- apresentar o resumo.
Cada responsabilidade pode mudar por um motivo diferente. A validação pode passar a rejeitar limite de quantidade; o cálculo pode incorporar taxas; a campanha pode trocar cupons; e a saída pode ganhar outro formato.
Comprimento é apenas um indício. O sinal mais útil é a presença de motivos de mudança independentes dentro do mesmo trecho.
Dê a cada parte um verbo e um resultado
Antes de pensar em sintaxe, escreva o algoritmo em blocos nomeados:
itensValidos <- VALIDAR ITENS(pedido.itens)
subtotal <- CALCULAR SUBTOTAL(itensValidos)
desconto <- DETERMINAR DESCONTO(subtotal, cupom)
total <- subtotal - desconto
APRESENTAR RESUMO(subtotal, desconto, total)
Esses nomes ainda não declaram funções ou procedimentos de uma linguagem. Eles formam um mapa de responsabilidades. A próxima aula mostrará como transformar esse mapa em construções executáveis.
Use o teste da frase: descreva cada bloco com um verbo, um objeto e um resultado observável.
| Bloco | Frase de responsabilidade | Resultado |
|---|---|---|
| validar itens | verificar se os itens podem participar do pedido | itens válidos ou erro |
| calcular subtotal | combinar preço e quantidade dos itens aceitos | valor antes do desconto |
| determinar desconto | aplicar a política comercial ao subtotal | valor do desconto |
| apresentar resumo | organizar os valores para o destinatário | saída compreensível |
Se a frase precisa de vários “e também”, provavelmente há responsabilidades misturadas. Se duas frases produzem exatamente o mesmo resultado, talvez a divisão esteja duplicando uma fronteira.
Nomes como processarDados, executarCoisas ou auxiliar não revelam intenção. Prefira ações do domínio que permitam prever o resultado sem ler todos os passos internos.
Faça os dados atravessarem fronteiras explícitas
O algoritmo organizado pode ser lido como uma transformação:
pedido bruto
→ itens válidos
→ subtotal
→ desconto e total
→ resumo apresentado
Esse fluxo retoma o modelo de entrada, processamento e saída, agora aplicado dentro de uma solução maior. Cada parte recebe uma entrada adequada ao seu trabalho e entrega um resultado que a próxima consegue usar.
Evite permitir que todas as partes leiam e alterem o pedido inteiro. Quando um bloco recebe somente os dados necessários, ficam mais claros:
- suas dependências;
- os casos que precisam ser testados;
- o resultado que ele promete;
- as mudanças que não deveriam afetá-lo.
Por exemplo, “determinar desconto” precisa conhecer subtotal e cupom. Não precisa decidir se um item possui quantidade válida nem como o resumo será exibido.
Esconda a decisão que tem maior chance de mudar
Dividir apenas pela ordem das etapas nem sempre produz a melhor fronteira. Uma orientação clássica de modularidade é concentrar decisões de projeto que podem mudar e expor uma interface estável para o restante da solução.
Imagine que a política comercial deixe de aceitar um código fixo e passe a considerar categoria do cliente e data da campanha. Se essa regra está concentrada em “determinar desconto”, as outras responsabilidades continuam recebendo e produzindo os mesmos conceitos:
entrada: subtotal e contexto comercial
resultado: valor de desconto válido
O algoritmo coordenador não precisa conhecer a tabela, a ordem das verificações ou a fórmula interna. Ele precisa apenas da promessa do bloco.
Isso é ocultação de informação: esconder uma decisão interna atrás de uma fronteira conhecida. Não significa esconder dados por esconder; significa impedir que detalhes mutáveis se espalhem por partes que não precisam deles.
Modularidade não garante impacto zero. Alterar o significado do desconto pode exigir novos dados de entrada ou uma nova apresentação. O ganho está em tornar essas consequências visíveis e evitar dependências acidentais.
Valide a reorganização sem mudar o comportamento
Separar partes de um algoritmo existente é uma refatoração quando melhora sua estrutura interna sem alterar o comportamento observável esperado.
Antes de reorganizar, registre casos que caracterizem a versão atual:
| Cenário | Subtotal | Cupom | Desconto esperado | Total esperado |
|---|---|---|---|---|
| sem cupom | 200 | ausente | 0 | 200 |
| cupom válido | 200 | CLIENTE10 | 20 | 180 |
| pedido gratuito | 0 | CLIENTE10 | 0 | 0 |
| quantidade inválida | — | qualquer | erro | nenhum total |
Execute os mesmos casos antes e depois da divisão. Se entradas equivalentes deixam de produzir os mesmos resultados, a mudança não foi apenas estrutural.
Confira também a ordem dos efeitos. Calcular o subtotal antes de validar todos os itens pode deixar estado parcial; apresentar o resumo antes de concluir o desconto gera saída inconsistente. Blocos melhor nomeados não corrigem automaticamente uma sequência errada.
Um teste de mesa ajuda a comparar valores e decisões nas duas versões.
Reutilização é possível, mas não obrigatória
Uma parte nomeada pode ser usada em mais de um fluxo. “Calcular subtotal” talvez sirva ao fechamento do pedido e à prévia do carrinho. Centralizar uma regra realmente compartilhada evita cópias que evoluem de maneiras diferentes.
Entretanto, reutilização não deve ser a única justificativa para separar. Um bloco usado uma única vez ainda pode:
- reduzir a quantidade de detalhes no fluxo principal;
- permitir teste isolado de uma regra delicada;
- dar nome a uma decisão importante;
- limitar o impacto de mudanças futuras.
O inverso também é verdadeiro: dois trechos apenas parecidos não deveriam compartilhar uma parte se representam regras que podem evoluir separadamente. Reutilize uma responsabilidade comum, não somente linhas com aparência semelhante.
Encontre o nível de divisão pelos custos de compreensão
Divisão insuficiente
Há poucos blocos quando cada um ainda exige acompanhar muitas regras, estados e efeitos ao mesmo tempo. Sintomas comuns:
- nome amplo que não antecipa o resultado;
- várias validações e cálculos independentes misturados;
- alteração simples exige reler o algoritmo inteiro;
- testes só conseguem verificar o fluxo completo.
Fragmentação excessiva
Há partes demais quando a leitura exige saltar continuamente entre nomes que pouco acrescentam. Sintomas:
- cada operação elementar recebe um bloco próprio;
- a coordenação fica maior que o trabalho realizado;
- entradas e resultados são repassados por muitas camadas sem transformação relevante;
- as partes nunca são compreendidas ou testadas isoladamente.
Fronteira inadequada
Mesmo uma quantidade razoável pode separar pelos critérios errados. Se validação de cupom aparece em três blocos, a decisão continua espalhada. Se “calcular valores” reúne subtotal, impostos, descontos e apresentação, o nome esconde múltiplos motivos de mudança.
Não existe número universal de linhas ou partes. Avalie se cada fronteira reduz o contexto necessário mais do que aumenta o custo de coordenação.
Use uma revisão em cinco perguntas
Para cada parte proposta, pergunte:
- Responsabilidade: consigo descrevê-la em uma frase sem vários “e também”?
- Fronteira: entradas e resultados estão claros?
- Conhecimento: ela conhece somente os dados e decisões necessários?
- Mudança: uma regra interna pode mudar sem obrigar a reescrever partes alheias?
- Verificação: consigo testar seu resultado com poucos casos focados?
Depois analise o conjunto:
- os blocos estão no mesmo nível de abstração?
- existe uma sequência compreensível entre eles?
- algum resultado não possui produtor ou consumidor claro?
- alguma regra aparece em mais de um lugar?
- a nova organização preservou o comportamento?
Essas perguntas são critérios de projeto, não uma pontuação automática. Duas divisões diferentes podem ser adequadas para mudanças esperadas diferentes.
Pratique reorganizando um boletim
Considere um algoritmo que:
- recebe quatro notas;
- rejeita valores fora de 0 a 10;
- calcula a média;
- classifica o estudante como aprovado, recuperação ou reprovado;
- apresenta notas, média e situação.
Faça o exercício em cinco etapas:
- escreva uma versão linear ou identifique as responsabilidades no fluxo existente;
- proponha blocos usando verbo e resultado;
- liste somente os dados necessários para cada bloco;
- crie casos que preservem limites como
0,5,7e10; - simule a mudança da regra de aprovação de média 7 para média 6 e desenhe o mapa de impacto.
Revise se a regra de classificação ficou concentrada, se a apresentação conhece detalhes desnecessários e se algum bloco foi criado apenas para executar uma operação trivial.
O que você deve guardar
Dividir um algoritmo em partes reduz a quantidade de decisões que precisam ser compreendidas simultaneamente. A fronteira é útil quando reúne uma responsabilidade coesa, declara os dados que recebe, entrega um resultado previsível e protege detalhes que podem mudar.
Não divida por uma meta de linhas nem suponha que toda parte precisa ser reutilizada. Compare benefícios de compreensão e teste com o custo de coordenação, e preserve o comportamento com casos executados antes e depois. A seguir, aprenda como transformar esses blocos conceituais em funções e procedimentos.
Referências
- Computer Science Teachers Association — Defining Computer Science. Acesso em 11 set. 2026.
- PARNAS, David L. On the Criteria To Be Used in Decomposing Systems into Modules. Communications of the ACM, v. 15, n. 12, p. 1053–1058, 1972.
- Carnegie Mellon Software Engineering Institute — A Guide to the Assessment of Software Development Methods. CMU/SEI-88-TR-8, 1988.
- Microsoft Learn — Extract and inline refactorings. Acesso em 11 set. 2026.