Blog /desenvolvimento

Paradigmas de programação: OO, funcional e procedural na prática

OO, funcional ou procedural — todo código segue uma filosofia. Entender os três paradigmas muda como você escreve e debate código.

7 min
Antes do Framework — série sobre fundamentos de desenvolvimento

Antes do Framework — Ep. 08

Você tem o ambiente configurado, sabe trabalhar em time e escolheu sua stack. Agora vem algo que a maioria dos tutoriais nunca explica diretamente: como o código pensa.

Toda linguagem foi projetada com uma filosofia por trás. Ignorar essa filosofia é como dirigir sem entender o que o câmbio faz: funciona até a primeira subida íngreme.


O que é um paradigma

Paradigma é a forma como você organiza o pensamento para resolver um problema com código.

Não é uma regra. É uma lente.

A mesma funcionalidade, "calcular o total de um pedido com desconto", pode ser resolvida de formas radicalmente diferentes dependendo do paradigma. E cada forma tem implicações reais em legibilidade, testabilidade e manutenção.


Os três paradigmas que aparecem no dia a dia

1. Procedural

O mais intuitivo. Você descreve o que o programa deve fazer, passo a passo.

def calcular_total(itens, desconto):
    total = 0
    for item in itens:
        total += item['preco'] * item['quantidade']
    return total * (1 - desconto)

itens = [
    {'preco': 50, 'quantidade': 2},
    {'preco': 30, 'quantidade': 1},
]

print(calcular_total(itens, 0.1))  # 117.0

Simples, linear, fácil de ler. Funciona bem para scripts, automações e lógica direta. O problema aparece quando o sistema cresce: funções que dependem de outras funções, estado compartilhado, difícil de testar partes isoladas.


2. Orientado a Objetos (OO)

O mais ensinado nos cursos. A ideia central: o mundo é composto de objetos que têm estado (atributos) e comportamento (métodos).

class Pedido:
    def __init__(self, itens, desconto=0):
        self.itens = itens
        self.desconto = desconto

    def total(self):
        subtotal = sum(i['preco'] * i['quantidade'] for i in self.itens)
        return subtotal * (1 - self.desconto)

pedido = Pedido(
    itens=[
        {'preco': 50, 'quantidade': 2},
        {'preco': 30, 'quantidade': 1},
    ],
    desconto=0.1
)

print(pedido.total())  # 117.0

OO brilha quando o sistema tem entidades reais que interagem: Pedido, Cliente, Produto, Pagamento. Você consegue modelar o domínio do negócio de forma natural.

Java, C#, Python e PHP são predominantemente OO. A maioria dos frameworks web que você vai usar são construídos em cima de OO.

O erro mais comum: tratar OO como obrigação e criar classes para tudo, inclusive para coisas que seriam mais simples como funções.


3. Funcional

Em vez de mudar estado, você transforma dados. Funções puras: mesma entrada sempre produz mesma saída, sem efeitos colaterais.

from functools import reduce

itens = [
    {'preco': 50, 'quantidade': 2},
    {'preco': 30, 'quantidade': 1},
]

# reduce acumula um resultado passando por cada elemento da lista
# lambda acc, i: define a função que recebe o acumulador e o item atual
subtotal = reduce(lambda acc, i: acc + i['preco'] * i['quantidade'], itens, 0)
total = subtotal * (1 - 0.1)

print(total)  # 117.0

Código funcional tende a ser mais previsível e fácil de testar, porque funções puras não dependem de estado externo.

JavaScript moderno abraça bastante funcional: map, filter, reduce. Python também mistura bem os paradigmas. Haskell e Elixir são funcionais puros.


Por que linguagens diferentes pensam diferente

Python é multiparadigma: você escolhe a abordagem que faz mais sentido para o problema. Java é fortemente OO: tudo é classe, a linguagem te força nessa direção. Go prefere composição e simplicidade, sem herança clássica. JavaScript mistura tudo e deixa você decidir, pra bem e pra mal.

Essa diferença filosófica é o motivo pelo qual um dev Java experiente que aprende Python às vezes escreve Python muito verboso e "javaesco". Ele está usando a ferramenta com a mentalidade errada.

Quando você entende os paradigmas, consegue usar cada linguagem do jeito que ela foi pensada, e esse código é sempre mais idiomático, mais legível e mais fácil de manter.


Na prática: os paradigmas coexistem

A maioria dos sistemas reais mistura os três.

Um backend Spring Boot (Java) vai usar:

  • OO para modelar entidades e serviços
  • Funcional nas Streams e lambdas para processar coleções
  • Procedural em scripts de migração e automações

Saber os três te deixa confortável para ler e escrever qualquer parte do sistema. Ficar preso em um único paradigma cria ponto cego.


O que muda quando você entende isso

Você começa a fazer perguntas melhores ao revisar código:

  • "Esse método deveria ser puro? Tem efeito colateral escondido aqui?"
  • "Essa classe está fazendo sentido como entidade ou eu criei só por criar?"
  • "Essa sequência de map e filter é mais legível do que o for que eu escreveria?"

Essas são perguntas de quem entende o porquê por trás das escolhas, não só o como.


→ Próximo episódio

Você entende como o código pensa. Agora vem como o código se organiza quando o sistema cresce. MVC não é só uma sigla de framework — é o padrão que aparece em Django, Spring, Laravel, Rails e praticamente todo backend que você vai encontrar no mercado.

Antes do Framework — Ep. 09: MVC na prática — como organizar um sistema antes de o framework fazer isso por você

Gostou do artigo?

Newsletter

Em breve

Em breve você poderá receber novos artigos direto no seu email.