📐 Capítulo 08: Padrões GRASP Avançados
Módulo 10: Paradigmas de Programação & Padrões de Projeto • Bloco 2: SOLID e GRASP
🏛️ A Sofisticação do Design Orientado a Objetos: Após dominar os padrões fundamentais de atribuição básica (Expert, Creator, Controller) e os critérios avaliativos (Low Coupling, High Cohesion), este capítulo explora o quarteto de ouro dos padrões avançados de Craig Larman: Polymorphism, Pure Fabrication, Indirection e o princípio-mãe de toda a engenharia de software sustentável: Protected Variations.
🗺️ Mapa Conceitual do Capítulo
flowchart TD
GRASP2["Padrões GRASP Avançados (Craig Larman)"]
GRASP2 --> POLY["1. Polymorphism (Polimorfismo)<br/>• Variações de comportamento por tipo delegadas a subclasses<br/>• Eliminação de cadeias if-else e switch de tipos"]
GRASP2 --> FAB["2. Pure Fabrication (Fabricação Pura)<br/>• Criação de classes artificiais sem lastro no mundo real<br/>• Repositórios, Serviços de Domínio, DAOs & Validadores"]
GRASP2 --> IND["3. Indirection (Indireção)<br/>• Inserção de um intermediário mediador<br/>• 'Todo problema se resolve com outro nível de indireção'"]
GRASP2 --> PV["4. Protected Variations (Variações Protegidas)<br/>• Identificação de pontos de instabilidade provável<br/>• Construção de contratos e interfaces blindadas"]
style GRASP2 fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px
style POLY fill:#e8f5e9,stroke:#4caf50,stroke-width:1.5px
style FAB fill:#fff3e0,stroke:#ff9800,stroke-width:1.5px
style IND fill:#fce4ec,stroke:#e91e63,stroke-width:1.5px
style PV fill:#ede7f6,stroke:#673ab7,stroke-width:1.5px
🎭 1. Polymorphism (Polimorfismo no GRASP)
“When related alternatives or behaviors vary by type (class), assign responsibility for the behavior—using polymorphic operations—to the types for which the behavior varies.” — Craig Larman
1.1 O Fim das Cadeias Condicionais
Em sistemas legados mal projetados, comportamentos que variam conforme o tipo de um registro são frequentemente espalhados em instruções condicionais procedurais:
# ANTI-PADRÃO: Polimorfismo negado via condicionais de tipo
def despachar_pedido(tipo_frete: str, pacote: Pacote):
if tipo_frete == "PAC":
...
elif tipo_frete == "SEDEX":
...
elif tipo_frete == "DRONE":
...
Se uma nova modalidade de entrega for homologada (ex.: entrega por bicicleta elétrica), o desenvolvedor precisa localizar e alterar todos os blocos if/elif espalhados pelo repositório.
O padrão Polymorphism orienta: atribua a responsabilidade à própria abstração polimórfica. Cada tipo concreto de frete (FretePac, FreteSedex, FreteDrone) implementa seu próprio método despachar(pacote).
- Sinergia: O padrão Polymorphism do GRASP é a técnica direta que viabiliza o Princípio Aberto/Fechado (OCP) do SOLID e o padrão comportamental Strategy do GoF.
🏭 2. Pure Fabrication (Fabricação Pura)
“Assign a highly cohesive set of responsibilities to an artificial or convenience class that does not represent a problem domain concept—something made up or purely fabricated to support high cohesion, low coupling, and reuse.” — Craig Larman
2.1 Decomposição Representacional vs. Decomposição Comportamental
Ao iniciar a modelagem orientada a objetos, os livros recomendam identificar os substantivos do mundo real: Cliente, Conta, Carro, Pedido. Isso é denominado Decomposição Representacional.
No entanto, sistemas de software corporativos possuem necessidades técnicas e algorítmicas que não existem no mundo real:
- Quem deve ser responsável por salvar um
Clienteem uma tabela PostgreSQL?- Se atribuirmos a persistência à classe
Cliente(seguindo cegamente o Information Expert, já queClientetem os dados), transformamos o domínio em uma God Class amarrada a drivers SQL, quebrando a High Cohesion e o Low Coupling.
- Se atribuirmos a persistência à classe
- A Resposta: Criamos uma Fabricação Pura (Pure Fabrication), como
ClienteRepositoryouClienteDAO.- Essa classe não existe no mundo real (um banco de dados físico não anda na rua cumprimentando clientes), mas ela é concebida artificialmente na arquitetura de software para isolar a infraestrutura e manter as classes conceituais limpas.
Decomposição Representacional (Mundo Real):
[Cliente] ──── Possui ────► [Contrato]
Decomposição via Fabricação Pura (Design Arquitetural):
[Cliente] ◄──── Gerenciado por ──── [ClienteRepository] (Pure Fab)
[Cliente] ◄──── Validado por ────── [ValidadorBiometria] (Pure Fab)
[Cliente] ◄──── Exportado por ───── [ExportadorJson] (Pure Fab)
2.2 Exemplos Consagrados de Fabricação Pura
- Padrão Repository & Data Mapper: Classes de persistência desacopladas do modelo de domínio.
- Domain Services (DDD): Classes que executam operações que envolvem múltiplas entidades sem pertencer conceitualmente a nenhuma delas (ex.:
TransferenciaBancariaService). - Adapters e Notificadores:
TwilioSmsAdapter,KafkaEventPublisher.
🔀 3. Indirection (Indireção)
“Assign the responsibility to an intermediate object to mediate between other components or services so that they are not directly coupled.” — Craig Larman
O aforismo célebre de David Wheeler (pioneiro britânico da computação) sintetiza esse princípio:
“All problems in computer science can be solved by another level of indirection, except for the problem of too many levels of indirection.”
3.1 O Papel do Intermediário
O padrão Indirection preconiza a inserção de um componente intermediário entre um emissor e um receptor para evitar o acoplamento direto ponto a ponto:
flowchart LR
subgraph DIRECT["Acoplamento Direto Ponto a Ponto (Rígido)"]
CLI1["Serviço Checkout"] --> G1["Stripe Gateway V1 API"]
end
subgraph INDIRECT["Indireção com Intermediário (Desacoplado)"]
CLI2["Serviço Checkout"] --> ADAPT["Adaptador Intermediário<br/>«IGatewayPagamento»"]
ADAPT --> G2["Stripe API V3"]
ADAPT --> G3["MercadoPago API"]
end
style DIRECT fill:#ffebee,stroke:#f44336,stroke-width:1.5px
style INDIRECT fill:#e8f5e9,stroke:#4caf50,stroke-width:1.5px
style ADAPT fill:#fff3e0,stroke:#ff9800,stroke-width:2px
3.2 Padrões GoF que São Manifestações de Indirection
Praticamente metade dos padrões de projeto estruturais e comportamentais do GoF derivam da aplicação de Indireção:
- Adapter: Interpõe um objeto intermediário para compatibilizar interfaces divergentes.
- Facade: Interpõe uma interface simplificada unificada à frente de um subsistema complexo.
- Proxy: Interpõe um substituto intermediário para controlar o acesso a um recurso pesado ou remoto.
- Mediator: Interpõe um coordenador central para evitar que dezenas de objetos conversem entre si em malha completa (mesh).
🛡️ 4. Protected Variations (Variações Protegidas)
“Identify points of predicted variation or instability; assign responsibilities to create a stable interface around them.” — Craig Larman
O padrão Protected Variations (PV) é considerado por teóricos da arquitetura de software como o princípio fundamental e unificador de todo o design sustentável:
- Qualquer sistema real sofrerá alterações: novas leis fiscais entrarão em vigor, provedores de nuvem mudarão suas APIs REST, bancos de dados relacionais serão substituídos por NoSQL, novos modelos de hardware surgirão.
- O engenheiro experiente não tenta impedir a mudança: ele identifica onde a mudança é provável e constrói uma interface estável ao redor desse ponto crítico de instabilidade, blindando o restante do sistema contra o impacto dessas oscilações.
flowchart TD
CORE["Núcleo de Regras de Negócio<br/>(Imune a mudanças externas)"]
CORE --> CONTRACT["«Interface Blindada»<br/>IProvedorAutorizacaoCartao"]
CONTRACT -.-> IMPL1["Adquirente Cielo (Driver Legado)"]
CONTRACT -.-> IMPL2["Adquirente Rede (Driver Atual)"]
CONTRACT -.-> IMPL3["Novo Gateway Cloud 2026"]
style CORE fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style CONTRACT fill:#ede7f6,stroke:#673ab7,stroke-width:2px
style IMPL1 fill:#f5f5f5,stroke:#9e9e9e,stroke-width:1px
style IMPL2 fill:#f5f5f5,stroke:#9e9e9e,stroke-width:1px
style IMPL3 fill:#f5f5f5,stroke:#9e9e9e,stroke-width:1px
4.1 A Relação Ancestral entre PV, OCP e Information Hiding
- O Princípio de Ocultamento de Informações (Information Hiding) de David Parnas (1972): Cada módulo deve ocultar um segredo de design (geralmente uma decisão técnica volátil).
- O Princípio Aberto/Fechado (OCP) de Bertrand Meyer (1988): Aberto para extensão, fechado para modificação.
- O Padrão Protected Variations de Craig Larman (1997): Formaliza como identificar os pontos de instabilidade e atribuir as responsabilidades através de polimorfismo e interfaces.
4.2 Protected Variations em Nível de Arquitetura de Sistemas
O padrão Protected Variations não se limita a classes e interfaces no mesmo processo de memória; ele é o fundamento das maiores inovações de arquitetura de sistemas distribuídos:
- APIs Versionadas (REST / gRPC): A interface pública de um microsserviço atua como a barreira de variações protegidas. Alterações internas no esquema de banco de dados do serviço não quebram clientes externos desde que o contrato HTTP/JSON continue sendo honrado.
- Tolerância a Falhas e Circuit Breakers: Quando um gateway bancário parceiro fica instável, um componente de indireção protegido intercepta o timeout e aciona um fallback automático sem propagar a pane para o usuário final.
- Máquinas Virtuais e Bytecode (JVM / .NET CLR): A especificação do bytecode é a interface estável definitiva que protege os desenvolvedores contra as centenas de variações de arquiteturas de processadores e sistemas operacionais subjacentes.
🌉 5. A Ponte Arquitetural: De GRASP para os 23 Padrões GoF
Muitos desenvolvedores aprendem os padrões GoF como receitas isoladas e sofrem para saber quando aplicá-los. Compreender o GRASP esclarece que os padrões GoF são apenas cristalizações técnicas avançadas dos princípios GRASP:
- GoF Strategy & State: São aplicações diretas de Polymorphism e Protected Variations para encapsular algoritmos ou estados variantes.
- GoF Adapter & Facade: São aplicações de Indirection e Pure Fabrication para reconciliar interfaces incompatíveis ou unificar subsistemas.
- GoF Factory Method & Abstract Factory: São especializações de Creator combinadas com Pure Fabrication para desonerar clientes do acoplamento direto com construtores.
- GoF Observer & Mediator: São refinamentos de Indirection e Low Coupling para viabilizar notificações desacopladas e orquestrações centralizadas.
Ao dominar as 9 diretrizes de Craig Larman, você deixa de memorizar diagramas de classes e passa a enxergar a motivação profunda por trás de cada padrão de software catalogado na indústria.
📊 6. Matriz Holística dos 9 Padrões GRASP
A matriz completa dos 9 padrões propostos por Craig Larman resume a sabedoria da modelagem orientada a objetos:
| Padrão GRASP | Categoria | Finalidade Arquitetural Primária |
|---|---|---|
| Information Expert | Fundamental / Atribuição | Colocar a lógica onde os dados residem, preservando encapsulamento. |
| Creator | Fundamental / Atribuição | Delegar a criação de objetos para seus agregadores naturais. |
| Controller | Fundamental / Atribuição | Receber eventos da UI e orquestrar fluxos sem misturar apresentação e domínio. |
| Low Coupling | Fundamental / Avaliativo | Minimizar a dependência entre módulos e bibliotecas. |
| High Cohesion | Fundamental / Avaliativo | Manter classes com responsabilidades estritamente focadas e coesas. |
| Polymorphism | Avançado / Variação | Tratar variações de tipo por operações polimórficas, eliminando switch/if. |
| Pure Fabrication | Avançado / Estrutura | Criar classes artificiais técnicas (DAOs, Repositories) para manter coesão. |
| Indirection | Avançado / Desacoplamento | Adicionar intermediários (Adapters, Mediators) para evitar acoplamento direto. |
| Protected Variations | Avançado / Resiliência | Blindar o sistema contra pontos previsíveis de volatilidade técnica ou legal. |
Ao dominar conjuntamente os princípios SOLID e as heurísticas GRASP, o arquiteto de software desenvolve um olhar clínico capaz de diagnosticar precocemente sintomas de degradação estrutural, projetando sistemas que acolhem requisitos emergentes com custo marginal decrescente e máxima confiabilidade.