Módulo 10: Paradigmas de Programação & Padrões de Projeto • Bloco 1: Paradigmas e Modelos • Demonstrações Práticas


1. Implementação Canônica em C: Carrinho de Compras Estruturado e Dinâmico

O programa em C abaixo implementa o processamento do Carrinho de Compras através do paradigma estruturado clássico:

  • Separação estrita entre os dados passivos (struct Item e struct Carrinho) e os procedimentos ativos.
  • Passagem de estruturas por ponteiro (Carrinho*) para permitir mutação in-place e evitar cópias pesadas de memória.
  • Gerenciamento dinâmico de capacidade no Heap via realloc e validação defensiva de status de retorno.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define STATUS_OK 0
#define STATUS_ERRO_MEMORIA -1
#define STATUS_ITEM_NAO_ENCONTRADO -2

typedef struct {
    char id[16];
    char nome[64];
    double preco_unitario;
    int quantidade;
    double aliquota_imposto; // ex.: 0.10 para 10%
} Item;

typedef struct {
    Item* itens;
    size_t total_itens;
    size_t capacidade;
    double frete_fixo;
    double desconto_cupom;
} Carrinho;

// -------------------------------------------------------------
// PROCEDIMENTOS DE GERENCIAMENTO DE CICLO DE VIDA
// -------------------------------------------------------------
int carrinho_inicializar(Carrinho* c, size_t capacidade_inicial, double frete) {
    c->itens = (Item*)malloc(capacidade_inicial * sizeof(Item));
    if (c->itens == NULL) return STATUS_ERRO_MEMORIA;
    c->total_itens = 0;
    c->capacidade = capacidade_inicial;
    c->frete_fixo = frete;
    c->desconto_cupom = 0.0;
    return STATUS_OK;
}

void carrinho_destruir(Carrinho* c) {
    if (c->itens != NULL) {
        free(c->itens);
        c->itens = NULL;
    }
    c->total_itens = 0;
    c->capacidade = 0;
}

// -------------------------------------------------------------
// OPERAÇÕES PROCEDURAIS DE MUTAÇÃO DE ESTADO
// -------------------------------------------------------------
int carrinho_adicionar_item(Carrinho* c, const char* id, const char* nome, double preco, int qtd, double imposto) {
    if (c->total_itens >= c->capacidade) {
        size_t nova_capacidade = c->capacidade * 2;
        Item* novo_bloco = (Item*)realloc(c->itens, nova_capacidade * sizeof(Item));
        if (novo_bloco == NULL) return STATUS_ERRO_MEMORIA;
        c->itens = novo_bloco;
        c->capacidade = nova_capacidade;
    }

    Item* item = &c->itens[c->total_itens++];
    strncpy(item->id, id, sizeof(item->id) - 1);
    item->id[sizeof(item->id) - 1] = '\0';
    strncpy(item->nome, nome, sizeof(item->nome) - 1);
    item->nome[sizeof(item->nome) - 1] = '\0';
    item->preco_unitario = preco;
    item->quantidade = qtd;
    item->aliquota_imposto = imposto;
    return STATUS_OK;
}

void carrinho_aplicar_cupom(Carrinho* c, double valor_desconto) {
    c->desconto_cupom = valor_desconto;
}

// -------------------------------------------------------------
// PROCEDIMENTO DE CÁLCULO E RELATÓRIO AGREGADO
// -------------------------------------------------------------
typedef struct {
    double subtotal_bruto;
    double total_impostos;
    double frete;
    double desconto;
    double total_liquido;
    const char* item_maior_subtotal;
} ResumoFinanceiro;

void carrinho_calcular_resumo(const Carrinho* c, ResumoFinanceiro* r) {
    r->subtotal_bruto = 0.0;
    r->total_impostos = 0.0;
    r->frete = c->frete_fixo;
    r->desconto = c->desconto_cupom;
    r->item_maior_subtotal = "Nenhum";

    double maior_sub = -1.0;

    for (size_t i = 0; i < c->total_itens; i++) {
        const Item* it = &c->itens[i];
        double sub = it->preco_unitario * it->quantidade;
        double imp = sub * it->aliquota_imposto;

        r->subtotal_bruto += sub;
        r->total_impostos += imp;

        if (sub > maior_sub) {
            maior_sub = sub;
            r->item_maior_subtotal = it->nome;
        }
    }

    double total = r->subtotal_bruto + r->total_impostos + r->frete - r->desconto;
    r->total_liquido = (total > 0.0) ? total : 0.0;
}

void imprimir_relatorio_carrinho(const Carrinho* c, const ResumoFinanceiro* r) {
    printf("=================================================================\n");
    printf("        RELATÓRIO DO CARRINHO (PARADIGMA ESTRUTURADO EM C)       \n");
    printf("=================================================================\n");
    printf("%-8s | %-24s | %6s | %10s | %10s\n", "ID", "Produto", "Qtd", "Unit (R$)", "Subtot(R$)");
    printf("-----------------------------------------------------------------\n");
    for (size_t i = 0; i < c->total_itens; i++) {
        const Item* it = &c->itens[i];
        double sub = it->preco_unitario * it->quantidade;
        printf("%-8s | %-24s | %6d | %10.2f | %10.2f\n",
               it->id, it->nome, it->quantidade, it->preco_unitario, sub);
    }
    printf("=================================================================\n");
    printf("Subtotal Bruto     : R$ %10.2f\n", r->subtotal_bruto);
    printf("Impostos (ICMS/ISS): R$ %10.2f\n", r->total_impostos);
    printf("Frete Fixo         : R$ %10.2f\n", r->frete);
    printf("Desconto de Cupom  : R$ %10.2f\n", r->desconto);
    printf("-----------------------------------------------------------------\n");
    printf("TOTAL LÍQUIDO      : R$ %10.2f\n", r->total_liquido);
    printf("Item de Maior Peso : %s\n", r->item_maior_subtotal);
    printf("=================================================================\n");
}

int main() {
    Carrinho meu_carrinho;
    carrinho_inicializar(&meu_carrinho, 2, 25.0);

    carrinho_adicionar_item(&meu_carrinho, "P01", "Monitor Ultrawide 34", 2800.0, 1, 0.12);
    carrinho_adicionar_item(&meu_carrinho, "P02", "Teclado Mecânico RGB", 350.0, 2, 0.08);
    carrinho_adicionar_item(&meu_carrinho, "P03", "Mouse Sem Fio 16000DPI", 180.0, 1, 0.08);
    carrinho_aplicar_cupom(&meu_carrinho, 150.0);

    ResumoFinanceiro resumo;
    carrinho_calcular_resumo(&meu_carrinho, &resumo);
    imprimir_relatorio_carrinho(&meu_carrinho, &resumo);

    carrinho_destruir(&meu_carrinho);
    return 0;
}

2. Processamento Imperativo com Acumuladores em Python

Em Python procedural, dados residem em dicionários e listas nativas, e procedimentos controlam laços e acumuladores mutáveis passo a passo:

# carrinho_imperativo.py

def criar_carrinho(frete: float = 20.0) -> dict:
    return {
        "itens": [],
        "frete": frete,
        "desconto_cupom": 0.0
    }

def adicionar_item(carrinho: dict, id_prod: str, nome: str, preco: float, qtd: int, imposto: float) -> None:
    carrinho["itens"].append({
        "id": id_prod,
        "nome": nome,
        "preco": preco,
        "quantidade": qtd,
        "imposto": imposto
    })

def aplicar_cupom(carrinho: dict, valor_desconto: float) -> None:
    carrinho["desconto_cupom"] = valor_desconto

def processar_fechamento_carrinho(carrinho: dict) -> dict:
    # Acumuladores explícitos manipulados iterativamente
    subtotal_bruto = 0.0
    total_impostos = 0.0
    maior_subtotal = -1.0
    item_destaque = None
    produtos_atacado = []

    for item in carrinho["itens"]:
        sub = item["preco"] * item["quantidade"]
        imp = sub * item["imposto"]

        subtotal_bruto += sub
        total_impostos += imp

        if sub > maior_subtotal:
            maior_subtotal = sub
            item_destaque = item["nome"]

        if item["quantidade"] >= 2:
            produtos_atacado.append(item["nome"])

    total_final = subtotal_bruto + total_impostos + carrinho["frete"] - carrinho["desconto_cupom"]
    if total_final < 0.0:
        total_final = 0.0

    return {
        "subtotal_bruto": subtotal_bruto,
        "total_impostos": total_impostos,
        "frete": carrinho["frete"],
        "desconto": carrinho["desconto_cupom"],
        "total_final": total_final,
        "item_mais_caro": item_destaque,
        "itens_atacado": produtos_atacado
    }

if __name__ == "__main__":
    c = criar_carrinho(frete=30.0)
    adicionar_item(c, "A1", "Cadeira Ergonômica", 1200.0, 1, 0.10)
    adicionar_item(c, "A2", "Suporte para Notebook", 80.0, 3, 0.05)
    adicionar_item(c, "A3", "Hub USB-C 7 portas", 150.0, 2, 0.08)
    aplicar_cupom(c, 100.0)

    resultado = processar_fechamento_carrinho(c)
    print("=== FECHAMENTO IMPERATIVO DO PEDIDO ===")
    for k, v in resultado.items():
        if isinstance(v, float):
            print(f"  {k:18s}: R$ {v:9.2f}")
        else:
            print(f"  {k:18s}: {v}")

3. Instruções de Compilação e Execução

Em C:

gcc -O2 -Wall 01_carrinho_c.c -o 01_carrinho_c
./01_carrinho_c

Em Python:

python carrinho_imperativo.py