Capítulo 13: Paradigmas de Programação: Imperativo, Orientado a Objetos e Funcional

Módulo 01: Fundamentos da Computação • Ciência da Computação Formal


🗺️ 1. Taxonomia e Comparativo dos Paradigmas de Programação

flowchart TD
    P["Paradigmas de Programação"] --> IMP["Imperativo / Estruturado
(Controle explícito de fluxo e mutabilidade)"]
    P --> OO["Orientado a Objetos
(Encapsulamento, Herança, Polimorfismo, SOLID)"]
    P --> FUNC["Funcional
(Imutabilidade, Funções Puras, Map/Filter/Reduce)"]

    style IMP fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px
    style OO fill:#ede7f6,stroke:#7e57c2,stroke-width:2px
    style FUNC fill:#e8f5e9,stroke:#4caf50,stroke-width:2px

🏛️ 2. Fundamentação Teórica

Um paradigma de programação molda a forma como o desenvolvedor modela a computação e estrutura os pensamentos lógicos para solucionar problemas de software.

2.1 Matriz Comparativa Estrutural

Dimensão de Análise Paradigma Imperativo Orientado a Objetos (OO) Paradigma Funcional
Unidade Primária Procedimentos e Comandos Objetos (Dados + Comportamento) Funções Puras Matemáticas
Gerenciamento de Estado Variáveis globais/locais mutáveis Estado mutável encapsulado Imutabilidade Estrita
Efeitos Colaterais Frequentes e encorajados Controlados via métodos Ausentes ou explicitamente isolados
Transparência Referencial Quase nula Baixa a moderada Total ($f(x)$ sempre retorna o mesmo valor)
Concorrência e Paralelismo Difícil (requer Locks manuais) Propenso a Race Conditions Trivial (dados imutáveis não requerem locks)

2.2 Os Princípios SOLID da Orientação a Objetos

Formulados por Robert C. Martin (“Uncle Bob”), os princípios SOLID guiam a construção de código orientado a objetos corporativo e manutenível:

  1. S — Single Responsibility Principle (SRP): Cada classe deve ter apenas uma única razão para mudar.
  2. O — Open/Closed Principle (OCP): Entidades de software devem ser abertas para extensão, mas fechadas para modificação.
  3. L — Liskov Substitution Principle (LSP): Objetos de uma superclasse devem poder ser substituídos por objetos de suas subclasses sem quebrar o sistema.
  4. I — Interface Segregation Principle (ISP): Clientes não devem ser forçados a depender de interfaces que não utilizam.
  5. D — Dependency Inversion Principle (DIP): Módulos de alto nível não devem depender de módulos de baixo nível; ambos devem depender de abstrações.

2.3 Fundamentos do Cálculo Lambda e Paradigma Funcional

Baseado no Cálculo Lambda de Alonzo Church (1936), o paradigma funcional trata funções como Cidadãos de Primeira Classe (First-Class Citizens):

  • Função Pura: O valor de retorno depende unicamente de seus parâmetros de entrada e não gera efeitos colaterais observáveis (I/O, mutação de arquivos ou variáveis externas).
  • Composição de Funções: Construção de lógicas complexas encadeando operações elementares ($f \circ g(x) = f(g(x))$).
  • Currying e Aplicação Parcial: Transformação de uma função de múltiplos argumentos $f(a, b)$ em uma cadeia de funções unárias $f(a)(b)$.

💻 3. O Mesmo Problema em Três Abordagens (Python)

from functools import reduce
from typing import List

# Problema: Filtrar números pares, dobrá-los e calcular o somatório total
dados = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 1. Abordagem Imperativa (Loops e Acumulador Mutável)
total_imperativo = 0
for x in dados:
    if x % 2 == 0:
        dobro = x * 2
        total_imperativo += dobro

# 2. Abordagem Orientada a Objetos (Processador Polimórfico)
class PipelineNumerico:
    def __init__(self, numeros: List[int]):
        self._numeros = numeros

    def executar(self) -> int:
        return sum(x * 2 for x in self._numeros if x % 2 == 0)

# 3. Abordagem Funcional Pura (Map, Filter, Reduce sem Mutação)
total_funcional = reduce(
    lambda acc, x: acc + x,
    map(lambda x: x * 2, filter(lambda x: x % 2 == 0, dados)),
    0
)

if __name__ == "__main__":
    print("=== COMPARAÇÃO DOS PARADIGMAS DE PROGRAMAÇÃO ===")
    print(f"Total Imperativo: {total_imperativo}")
    print(f"Total OO:         {PipelineNumerico(dados).executar()}")
    print(f"Total Funcional:  {total_funcional}")
    assert total_imperativo == total_funcional == 60, "Inconsistência nos resultados!"