Skip to content

Reboredo.bit

Menu
  • Início
  • Sobre mim
  • Posts
Menu
Eyeglasses reflecting computer code on a monitor, ideal for technology and programming themes.

Explorando Paradigmas: Estrutural vs. Orientação a Objetos

Posted on 25 de novembro de 202526 de novembro de 2025 by victoreboredo.dev@gmail.com

Lembro da primeira vez que tentei estudar a diferença entre programação estruturada e orientação a objetos. Comecei com exemplos, diagramas, até código. Mas a pergunta que ficou no ar era até simples: “E qual é melhor?”. Passei um bom tempo acreditando ter a resposta definitiva. Hoje, reconheço que essa pergunta estava mal formulada desde o início. Volto então para a resposta que cai nas graças de todo desenvolvedor experiente: “depende”.

A verdade é que paradigmas de programação são ferramentas, não religiões. E como toda ferramenta, cada uma tem seu contexto ideal de aplicação. Para fazer uma escolha coerente, é necessário lançar fora essa dicotomia equivocada que nossa bolha criou com o tempo.


O que cada paradigma realmente prioriza

Antes de entrar em comparações, precisamos entender o que cada abordagem fundamentalmente valoriza.

A programação estruturada nasceu da necessidade de disciplinar o caos dos GOTOs. Seus três pilares — sequência, decisão e iteração — são elegantes em sua simplicidade. Um programa estruturado é, essencialmente, uma sequência finita de passos, onde podemos tomar decisões (if-else, switch-case) e repetir operações (for, while, do-while) conforme necessário.

Quando pensamos neste paradigma, deveríamos pensar em um fluxograma bem definido. Cada função ou procedimento é uma sub-rotina (hoje em dia utilizamos basicamente as funções) especializada. Os dados fluem pelo sistema, sendo transformados ao longo do caminho. É linear, previsível e — para problemas adequados — elegante.

A Programação Orientada a Objetos propõe uma mudança fundamental de perspectiva. Em vez de pensar em “o que o programa faz”, pensamos em “quais entidades existem e como elas interagem”. A orientação a objetos é atemporal — não está presa a uma linguagem específica porque representa uma forma de pensar sobre problemas.

Um sistema orientado a objetos é uma simulação. Objetos são entidades (concretas ou abstratas) que encapsulam estado (atributos) e comportamento (métodos). Eles se comunicam, colaboram e evoluem. O design gira em torno dessas entidades, suas responsabilidades e relacionamentos.

A grande promessa desse paradigma é organização: dados e operações relacionadas caminham juntos. Não mais aquela confusão de “qual função manipula qual dado” que assombra sistemas estruturados grandes.

Quando a estrutura mostra suas fraturas

O problema fundamental da programação estruturada, como Thiago Leite e Carvalho observa em seu livro, é que “dados e operações de diversos conceitos são misturados”. Não fica claro quais funções realmente pertencem a quais dados. À medida que a complexidade cresce, esse emaranhado se torna ingerenciável.

Alguns sintomas que vivenciamos em projetos grandes que utilizam o paradigma estruturado:

  1. Repetição massiva de código: a mesma lógica de validação espalhada por dez funções diferentes.
  2. Funções gigantes: aquela função de 500 linhas que faz “um pouco de tudo”.
  3. Dependências invisíveis: alterar uma variável global e rezar para nada quebrar.
  4. Testes frágeis: impossível testar uma função sem configurar metade do sistema.

A programação estruturada tem seu lugar. Para scripts, algoritmos isolados, processamento de dados lineares, ela é perfeita. O problema surge quando tentamos modelar domínios complexos com ela.

A promessa (e as armadilhas) da Orientação a Objetos

POO chegou como salvador. Classes, encapsulamento, herança, polimorfismo — ferramentas poderosas para organizar complexidade. E realmente são, quando bem aplicadas.

Deixe-me destacar os conceitos que, na minha opinião, fazem a diferença real:

Coesão: uma classe deve ter uma responsabilidade bem definida. O princípio de responsabilidade única (SRP) do SOLID não é apenas teoria — é sobrevivência. Quando cada classe tem um propósito claro, o código se torna intuitivo. Você sabe onde procurar quando algo precisa mudar.

Baixo acoplamento: classes devem depender de abstrações, não de implementações concretas. Aqui entram interfaces e inversão de dependência. Essa foi a lição mais valiosa que aprendi. Quando suas classes dependem de contratos (interfaces), você pode trocar implementações sem quebrar nada. Testabilidade surge naturalmente.

Encapsulamento: não é sobre colocar private em tudo. É sobre esconder decisões de implementação e expor apenas o necessário. Uma classe bem encapsulada protege seus invariantes — você não consegue colocá-la em estado inválido de fora.

Abstração: focar no essencial, ignorar o irrelevante. Uma boa abstração captura a essência de uma entidade sem se perder em detalhes. Mas cuidado — abstrações ruins são pior que código duplicado.

Onde a Orientação a Objetos tropeça…

Mas POO não é bala de prata. Já vi (e cometi) os seguintes pecados:

Over-engineering absurdo: hierarquias de classes com seis níveis de profundidade para resolver um problema que cabia em três funções. Design patterns aplicados religiosamente, mesmo quando desnecessários.

Anemic Domain Models: classes que são apenas sacos de dados, com toda lógica em “services”. Essencialmente programação estruturada disfarçada de POO.

Herança maluca: tentei usar herança para tudo. “Gato é um Animal” — linda teoria. Na prática, quando Animal ganhou 20 métodos que só faziam sentido para alguns filhos, a hierarquia virou um pesadelo.

God Objects: aquela classe que sabe demais, faz demais, controla demais. Baixa coesão, alto acoplamento — tudo que não queremos.


Trade-offs importantes

Performance vs. Organização

Sim, POO pode ter overhead. Objetos ocupam memória. Dispatch dinâmico (polimorfismo) tem custo. Mas aqui está a verdade: na maioria dos sistemas, isso não importa.

Escrevi um microserviço que processava milhões de transações por dia. Orientado a objetos, bem organizado, testado. Nunca foi gargalo. Quando finalmente tivemos problemas de performance, eram queries SQL mal otimizadas, não a “lentidão de objetos”.

Exceções existem. Sistemas embarcados, jogos de alta performance, processamento científico — nesses contextos, código estruturado ou até assembly pode ser necessário. Mas são exceções, não a regra.

Clareza vs. Flexibilidade

Código estruturado bem escrito é cristalino. Você lê de cima para baixo, entende o fluxo, segue a lógica. Direto ao ponto.

Tal paradigma adiciona camadas de indireção. Para entender o que acontece, você navega por classes, interfaces, composições. Isso é flexibilidade — você pode estender sem modificar. Mas também é complexidade.

O truque é saber quando vale a pena. Para um script de 50 linhas que processa um CSV? Provavelmente não. Para um ERP com 100 desenvolvedores e evolução contínua? Absolutamente.

Testabilidade

Aqui, POO bem feita vence disparado. Injeção de dependência + interfaces = facilidade absurda para testar. Você mocka dependências, testa comportamentos isoladamente, tem confiança para refatorar.

Funções puras (conceito emprestado da programação funcional mas aplicável em P.E.) também testam trivialmente. O problema são funções impuras que dependem de estado global — aí vira pesadelo.

Composição sobre Herança: a lição que demorei a aprender

Herança parece tão natural no início. “Cachorro é um Animal”, “ContaCorrente é uma Conta”. O problema surge quando você precisa de comportamentos que não se encaixam na hierarquia.

Exemplo real: tinha uma hierarquia Veiculo > VeiculoTerrestre > Carro. Depois precisei adicionar VeiculoAmphibio. Ele é terrestre? É aquático? Ambos? A hierarquia quebrou.

A solução moderna é composição. Em vez de “é um” (is-a), pense “tem um” (has-a). Um Carro tem um Motor, tem Rodas, tem capacidades de locomoção. Você compõe comportamentos.

Interfaces ajudam muito aqui. Defina contratos (IMovel, ILigavel) e implemente em diferentes classes. Flexibilidade sem acoplamento rígido de herança.

Quando voltar para o estruturado

Sim, às vezes faz sentido. Nem tudo precisa ser objeto.

Funções utilitárias: conversões, validações simples, cálculos matemáticos. Um método estático ou função pura resolve sem cerimônia.

Scripts e automações: processamento batch, ETL simples — estruturado é direto e eficiente.

Performance crítica: inner loops, processamento massivo de dados — funções puras, sem overhead de objetos.

Algoritmos puros: ordenação, busca, parsing — a estrutura do problema já é algorítmica. Forçar POO aqui é contorcionismo.

O segredo é híbrido pragmático. Tenho serviços (objetos) que orquestram lógica de negócio, mas usam funções utilitárias puras para transformações de dados. Best of both worlds.


Conclusão: pragmatismo sobre dogma

Vinte anos atrás, POO era a resposta para tudo. Hoje, vivemos o renascimento funcional (Elixir, Clojure, até Java com Streams). Amanhã, quem sabe? Linguagens híbridas (Kotlin, Scala, Swift) misturam paradigmas com maestria.

A lição que levo é: paradigmas são ferramentas cognitivas. Estruturado ensina sobre fluxo e decomposição. POO ensina sobre modelagem e responsabilidades. Funcional ensina sobre composição e imutabilidade.

Aprenda todos. Entenda as forças e limitações. E, principalmente, escolha baseado no problema, não em preferências pessoais.

Como Thiago Leite e Carvalho coloca em seu livro, que foi base para esse estudo: a orientação a objetos não está ligada a uma linguagem específica — você pode investir tempo aprendendo esses conceitos porque eles são atemporais. Mas o mesmo vale para programação estruturada. São ferramentas no seu cinto de utilidades.

O código que escrevo hoje é diferente do que escrevia há dez anos. Menos hierarquias profundas, mais composição. Menos classes, mais funções quando apropriado. Menos dogma, mais pragmatismo.

E sabe o melhor? O código ficou mais simples, mais testável e mais fácil de manter. Não porque segui um paradigma religiosamente, mas porque aprendi quando e como usar cada ferramenta.

Essa é a verdadeira arte da engenharia de software: saber escolher.


Referências

Robert C. Martin (Uncle Bob) – Princípios SOLID e Clean Code

André Baltieri – Post sobre Orientação a Objetos

Thiago Leite e Carvalho – “Orientação a Objetos: Aprenda seus conceitos e suas aplicabilidades de forma efetiva”, Casa do Código

Maurício Aniche – “Orientação a Objetos e SOLID para Ninjas”, Casa do Código

1 7xeqn6jmecf7ksgj ckahq
orientacaoaobjetos ebook large
orientacaoaobjetosesolidparaninjas ebook large

Navegação de Post

De TypeScript a Golang: Saindo da zona de conforto →

1 thought on “Explorando Paradigmas: Estrutural vs. Orientação a Objetos”

  1. Pingback: De TypeScript a Golang: Saindo da zona de conforto -

Deixe um comentário Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Recent Posts

  • Microsserviços: 5 Lições Aprendidas — Um Olhar Arquitetural
  • 5 Pilares financeiros que destacam negócios de alto valor
  • Princípio da Responsabilidade Única e as implicações na Orientação a Objetos e Arquitetura de Software
  • (D): Aplicando o “Princípio da Inversão de Dependências” com Typescript e Java
  • (I): Aplicando o “Princípio da Segregação da Interface” com Typescript e Java

Archives

  • novembro 2025

Categories

  • Empreendimento (1)
  • Engenharia (9)
  • Finança (2)
  • Java (6)
  • Liderança (1)
  • Orientação a Objetos (8)
  • Programação (9)
  • Programação Estruturada (2)
  • Typescript (8)
© 2025 Reboredo.bit | Powered by Minimalist Blog WordPress Theme