Pular para conteúdo

Projeto 11: Padrões Criacionais: Builder Fluente e Prototype 🏗️

Escopo do Projeto

Objetivo: Dominar os padrões Builder com interface fluente (Fluent Interface) para construção de objetos complexos e Prototype para clonagem profunda (Deep Copy) de templates em memória.


🎯 1. Contexto & Desafio Prático

A instanciação de objetos complexos (como consultas SQL parametrizadas, configurações de servidores ou requisições HTTP) com construtores telescópicos é propensa a erros de parâmetro. Você projetará um HttpRequestBuilder fluente para construção de requisições e um mecanismo Prototype para clonagem de instâncias com deep copy.


📋 2. Requisitos Técnicos Obrigatórios

  • R1 (Builder Fluente): Implementar RequestBuilder com encadeamento de métodos (.with_method(), .with_header(), .with_body(), .build()).
  • R2 (Imutabilidade do Produto Final): O objeto gerado após o .build() deve ser imutável e validado contra configurações obrigatórias faltantes.
  • R3 (Padrão Prototype): Implementar interface clone() com cópia profunda (copy.deepcopy), permitindo criar templates pré-configurados.
  • R4 (Validação de Parâmetros): Lançar exceções claras caso a URL ou o método HTTP não tenham sido informados no build.

📐 3. Diagrama Conceitual & Arquitetura

graph LR
    Builder["HttpRequestBuilder()"] --> M1[".set_method('POST')"]
    M1 --> M2[".set_url('https://api.empresa.com')"]
    M2 --> M3[".add_header('Authorization', 'Bearer token')"]
    M3 --> Build[".build()"]
    Build --> Request["Objeto HttpRequest Imutável & Validado"]
    Request --> Clone[".clone() (Prototype Deep Copy)"]
    Clone --> ClonedReq["Nova Instância Independente"]
    style Builder fill:#e1f5fe,stroke:#01579b
    style Build fill:#fff3e0,stroke:#e65100
    style Request fill:#e8f5e9,stroke:#2e7d32
    style ClonedReq fill:#f3e5f5,stroke:#7b1fa2

💻 4. Especificação Técnica & Código de Referência

// fluent_builder_prototype.py
import copy

class HttpRequest:
    def __init__(self, method: str, url: str, headers: dict, body: str = None):
        self.method = method
        self.url = url
        self.headers = headers
        self.body = body

    def clone(self):
        return copy.deepcopy(self)

class HttpRequestBuilder:
    def __init__(self):
        self._method = "GET"
        self._url = None
        self._headers = {}
        self._body = None

    def with_method(self, method: str):
        self._method = method
        return self

    def with_url(self, url: str):
        self._url = url
        return self

    def with_header(self, key: str, value: str):
        self._headers[key] = value
        return self

    def build(self) -> HttpRequest:
        if not self._url:
            raise ValueError("URL é obrigatória para construir HttpRequest")
        return HttpRequest(self._method, self._url, self._headers, self._body)

📦 5. Critérios de Avaliação e Entrega

  1. Construção de requisições fluentes encadeadas funcionando.
  2. Clonagem de protótipo comprovando isolamento de memória de dicionários internos.
  3. Validação defensiva no método .build() impedindo objetos inválidos.