Módulo 14 - Imutabilidade e efeitos: código previsível

Efeito colateral controlado: isolar na borda

8 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 12/07/2026

O que você vai aprender

  • Definir efeito colateral e reconhecer que ele é necessário.
  • Separar a decisão (pura) da execução do efeito (impura).
  • Empurrar os efeitos para a borda e manter o miolo puro.
  • Entender por que isso facilita testar e mudar o programa.

Efeitos são necessários, não vilões

É fácil sair da aula anterior achando que efeito colateral é coisa ruim. Não é. Um programa que não salva nada, não mostra nada e não fala com ninguém é inútil. O efeito é o ponto onde o software encosta no mundo: gravar o pedido, exibir o resultado, enviar a notificação. A pureza nunca foi sobre banir o efeito, e sim sobre não deixá-lo vazar para onde não precisa. Quando cada função calcula um pouco e ainda imprime, salva e chama a rede no meio do caminho, o programa vira uma teia em que qualquer mudança pode disparar uma consequência inesperada em outro lugar. O efeito espalhado é o que dói, não o efeito em si.

A saída madura é separar duas perguntas que costumam se misturar: o que fazer e fazer. Decidir o que fazer é lógica, e lógica pode ser pura: dado o carrinho, qual o total, qual o desconto, qual a mensagem a exibir. Fazer, de verdade, é o efeito: gravar esse total no banco, pintar essa mensagem na tela. Quando você mantém a decisão pura e empurra a execução para uma camada fina na beirada, ganha um miolo previsível cercado por uma casca pequena que mexe no mundo. Essa casca é a única parte imprevisível, e por ser pequena, é fácil de vigiar.

Um alvo em anéis. No centro, um círculo grande rotulado núcleo puro, com ícones de cálculo e decisão. Em volta, um anel fino rotulado borda impura, com ícones de salvar, imprimir e rede, tocando o mundo externo desenhado do lado de fora. Setas mostram os dados entrando na borda, indo puros para o núcleo decidir, e voltando à borda para o efeito ser executado.
Núcleo puro decide; borda fina executa os efeitos. O imprevisível fica confinado na casca.

Separar decidir de executar

Veja a diferença na prática. Uma versão embaralhada calcula o valor da conta e, no meio do cálculo, já imprime avisos e salva no arquivo. Fica impossível testar o cálculo sem disparar as impressões e mexer no arquivo. A versão organizada quebra em duas: uma função pura que recebe os dados e devolve uma descrição do que precisa acontecer, e uma função de borda que pega essa descrição e executa. A pura você testa numa linha; a de borda é curta e faz só o efeito. A lógica interessante, aquela que erra e precisa de cuidado, mora toda no lado puro, onde o teste é barato.

// NÚCLEO PURO: decide, não executa
função decidirCobranca(carrinho, cupom)
  total <- somar(carrinho)
  desconto <- calcularDesconto(total, cupom)
  retorne { valor: total - desconto, mensagem: "Cobrança pronta" }
fim

// BORDA IMPURA: só executa o que o núcleo decidiu
função processar(carrinho, cupom)
  plano <- decidirCobranca(carrinho, cupom)   // parte pura
  salvarNoBanco(plano.valor)                  // efeito
  escreva(plano.mensagem)                      // efeito
fim

decidirCobranca é pura e testável; processar é a casca fina que executa os efeitos decididos.

🎮 Jogo da aula

Puro ou tem efeito colateral?

Cada trecho é lógica pura (só calcula e devolve) ou tem efeito colateral (toca o mundo externo)? Classifique.

A vantagem de isolar na borda

Isolar o efeito na borda paga em três frentes. Primeira, teste: o núcleo puro se testa sem montar banco nem simular rede, e a borda é tão curta que sobra pouco para dar errado. Segunda, mudança: se amanhã você troca o banco de dados por outro, ou a tela por um aplicativo, só a borda muda; o miolo que decide continua igual, porque ele nunca soube que banco ou tela existiam. Terceira, entendimento: quem lê o código encontra a lógica reunida num lugar limpo, sem tropeçar em impressões e gravações no meio do raciocínio. O efeito continua lá, o programa continua fazendo tudo, mas a parte imprevisível fica pequena, nomeada e num canto só.

Teste rápido

O que significa isolar os efeitos colaterais na borda do sistema?

Perguntas frequentes

Se o efeito é necessário, por que tanto cuidado para separá-lo?
Porque efeito misturado com lógica contamina tudo. Uma função que calcula e ao mesmo tempo salva não pode ser testada sem disparar a gravação, e não pode ter o cálculo reaproveitado sem carregar o efeito junto. Separar não elimina o efeito, apenas o confina. A lógica fica limpa e testável, e o efeito fica num canto pequeno, fácil de trocar e vigiar.
O que exatamente conta como efeito colateral?
Tudo que a função faz além de devolver um valor a partir dos argumentos: escrever na tela, salvar ou ler um arquivo, alterar um dado compartilhado, chamar a rede, ler o relógio, sortear um número. Se remover essa ação mudaria o mundo fora da função, é efeito colateral. Devolver um resultado, por si só, não é efeito.
Como fica o teste da parte que tem efeito?
A ideia é deixar a borda tão fina que quase não tenha lógica para testar: ela só chama o efeito com o que o núcleo decidiu. O grosso do teste recai sobre o núcleo puro, que é barato de testar. Para a borda, quando preciso, usam-se dublês que fingem o banco ou a rede, mas como ela é curta, esse esforço é pequeno.
Isso não vai encher o programa de funções pequenas?
Vai criar mais funções, sim, mas pequenas e com um propósito claro cada uma. Isso costuma ser bom: peças pequenas e nomeadas são mais fáceis de entender, testar e reusar do que uma função gigante que faz tudo. O ganho de clareza compensa o número maior de funções, principalmente quando o programa cresce e precisa mudar.
Esse padrão tem um nome?
É conhecido como núcleo funcional com casca imperativa, ou núcleo puro com borda impura. A ideia central é a mesma: um miolo de funções puras que decide, cercado por uma camada fina que executa os efeitos. Você encontra variações desse princípio em muitos estilos de arquitetura, sempre com o objetivo de separar a decisão da execução.
Vale a pena isolar efeitos até num programa pequeno?
Em programas muito pequenos o ganho é modesto, e às vezes misturar é aceitável. Mas o hábito ajuda desde cedo, porque programas pequenos crescem. Separar a decisão da execução custa pouco quando você já pensa assim, e evita a dor de desembaraçar efeito de lógica mais tarde, quando o código já ficou grande e emaranhado.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.