SkillsTecnológicas
Menu
Conteúdo da trilha

Conteúdo 4 de 6

Como decompor um problema

Divida problemas complexos em partes menores, verificáveis e mais fáceis de resolver.

Publicado em 9 de setembro de 202614 min de leituraSkills Tecnológicas

Um fluxo complexo é separado em quatro partes conectadas que chegam a um resultado verificado

Decompor é transformar um problema grande em partes administráveis

Decompor um problema significa dividi-lo em subproblemas menores, com responsabilidades e resultados claros. A finalidade não é apenas criar uma lista de tarefas: é reduzir a quantidade de detalhes que precisam ser compreendidos ao mesmo tempo sem perder as relações importantes entre as partes.

Na aula de pensamento computacional, a decomposição apareceu como uma prática integrada a padrões, abstração e algoritmos. Agora veremos um método para aplicá-la.

Comece pelo problema, não pelas partes

Antes de dividir, registre quatro elementos:

  • objetivo: qual resultado precisa ser alcançado;
  • entrada: quais dados ou recursos estarão disponíveis;
  • restrições: quais limites e regras devem ser respeitados;
  • critério de sucesso: como saberemos que o problema foi resolvido.

Considere “processar um pedido de uma loja virtual”. O objetivo pode ser transformar um pedido recebido em pagamento confirmado e entrega preparada. Restrições incluem estoque disponível, endereço válido e pagamento autorizado. Sem essa definição, a divisão corre o risco de organizar a tarefa errada.

Um método para encontrar subproblemas

1. Identifique as grandes responsabilidades

Pergunte quais resultados intermediários precisam existir para chegar ao objetivo. No pedido, podemos identificar: validar os dados, calcular o total, cobrar e preparar a entrega.

2. Defina a entrada e a saída de cada parte

“Validar pedido” recebe dados brutos e devolve um pedido válido ou um erro explicado. “Calcular total” deve receber apenas um pedido já validado e devolver os valores calculados.

3. Mapeie dependências

Calcular o total depende da validação? A cobrança depende do total? Tornar essas relações explícitas impede que uma parte espere um dado que ainda não existe.

4. Continue dividindo quando houver complexidade útil

“Preparar entrega” ainda pode reunir separação, embalagem, etiqueta e despacho. Divida novamente somente quando a nova parte ganhar uma responsabilidade clara e puder ser compreendida ou testada melhor.

5. Pare no nível adequado

Uma parte como “somar 1 ao contador” pode ser pequena demais para ajudar nessa etapa. A decomposição termina quando cada unidade é suficientemente simples para ser planejada e suficientemente relevante para merecer um nome.

Processar pedido dividido em validar, calcular total, cobrar e preparar entrega
A árvore mostra responsabilidades, não a ordem completa de execução; dependências são analisadas separadamente.

Como reconhecer um bom subproblema

Um subproblema útil apresenta coesão: seus passos contribuem para uma responsabilidade principal. Ele também possui uma fronteira compreensível com as outras partes.

Use estas perguntas:

  • O nome descreve um único resultado?
  • Está claro o que entra e o que sai?
  • É possível explicar a parte sem narrar o sistema inteiro?
  • Ela pode ser testada separadamente?
  • Mudanças internas podem ocorrer sem alterar todas as outras partes?
  • Há menos dependências do que haveria em outra divisão possível?
Lista visual com objetivo único, fronteira clara, entradas e saídas e teste independente
Esses critérios ajudam a avaliar a divisão; não constituem uma fórmula automática.

Defina contratos entre as partes

Uma divisão só funciona quando as partes conseguem colaborar. Para cada subproblema, escreva um contrato simples:

  1. responsabilidade;
  2. dados de entrada;
  3. resultado de saída;
  4. erros possíveis;
  5. condições que precisam ser verdadeiras antes da execução.

No exemplo:

responsabilidade: validar pedido
entrada: itens e endereço informados
saída: pedido válido ou erro explicado
regra: todos os itens precisam existir e o endereço deve estar completo

Esse contrato não define ainda uma API ou função. Ele evita ambiguidade no raciocínio e permite desenvolver o algoritmo interno depois.

Pedido bruto entra na validação e produz pedido válido ou erro explicado
Entradas e saídas explícitas tornam a relação entre subproblemas verificável.

Decomposição não é necessariamente sequência

Uma árvore de partes responde “do que o problema é composto?”. Um fluxo responde “em qual ordem as ações ocorrem?”. Confundir as duas representações pode esconder dependências ou sugerir uma ordem que não existe.

Algumas partes são sequenciais; outras podem ocorrer de forma independente. A embalagem depende da validação dos itens, mas certas verificações de endereço e estoque talvez possam ser realizadas separadamente. Primeiro defina responsabilidades; depois construa o algoritmo que coordena sua execução.

Erros comuns ao dividir um problema

Separar por tamanho, não por responsabilidade

Quatro blocos com a mesma quantidade de passos não são necessariamente uma boa divisão. Prefira unidades com propósito coeso.

Criar partes que conhecem tudo

Se cada subproblema precisa acessar todos os dados e regras, as fronteiras não reduziram a complexidade. Reveja entradas, saídas e responsabilidades.

Ignorar dependências

Duas partes podem parecer independentes até ambas alterarem o mesmo dado. Registre quem produz, consome e modifica cada informação relevante.

Dividir cedo demais

Sem compreender o objetivo, a estrutura reflete suposições. Defina problema e critérios antes de escolher partes.

Dividir indefinidamente

Detalhar cada operação elementar deixa o mapa maior que o problema. Pare quando as partes já puderem ser planejadas e verificadas.

Pratique com um sistema de biblioteca

Decomponha o problema “realizar um empréstimo de livro”. Considere cadastro do leitor, disponibilidade do exemplar, limite de empréstimos, registro e data de devolução.

Crie uma árvore com três a cinco responsabilidades. Para cada uma, escreva entrada, saída e erro possível. Depois desenhe as dependências e teste dois cenários: empréstimo aprovado e leitor que atingiu o limite.

Revise se algum bloco faz coisas demais, se dois blocos possuem a mesma responsabilidade ou se uma saída necessária não tem produtor.

O que você deve guardar

Uma boa decomposição preserva o objetivo enquanto separa responsabilidades coesas, explicita dependências e define como as partes trocam informações. Ela reduz a complexidade, favorece testes e permite construir a solução progressivamente.

Consulte o catálogo da trilha de Lógica de Programação. O próximo conteúdo organiza essas partes pelo modelo de entrada, processamento e saída.

Referências