Prévia do material em texto
📌 PADRÕES GRASP – Princípios de Atribuição de Responsabilidades São diretrizes para decidir quem faz o quê no sistema. Especialista na Informação: Use quando uma operação precisa ser executada e você quer colocar a responsabilidade na classe que tem os dados necessários. Exemplo: Em um sistema de e-commerce, quem calcula o total do pedido? A classe Pedido , pois ela tem a lista de itens. Aplicação: Evita "classes faz-tudo" e centraliza a lógica onde os dados estão. Criador: Use para decidir quem deve instanciar um objeto. A regra é: a classe que agrega, contém ou usa intensivamente o objeto deve criá-lo. Exemplo: Um Pedido cria seus próprios Itens no método adicionarItem() . Aplicação: Mantém o controle do ciclo de vida dos objetos e reduz acoplamento. Coesão Alta: Uma classe deve ter responsabilidades bem definidas e relacionadas. Evite classes que fazem de tudo. Exemplo: Separe a lógica de negócio ( Pedido ) da lógica de persistência ( PedidoRepository ). Aplicação: Facilita manutenção, testes e reuso. Controlador: Recebe eventos externos (como requisições web) e coordena a execução, sem conter lógica de negócio. Exemplo: Um Controller em frameworks MVC (Spring, Django, ) que recebe uma requisição e chama os serviços apropriados. Aplicação: Desacopla a interface do usuário da lógica de negócio. Acoplamento Baixo: Minimize dependências entre classes. Prefira interfaces a implementações concretas. Exemplo: Em vez de uma classe PedidoService depender diretamente de PedidoRepositoryMySQL , faça-a depender de uma interface PedidoRepository . Aplicação: Facilita mudanças (trocar banco de dados) e testes (mocks). Polimorfismo: Use interfaces ou classes abstratas para tratar diferentes comportamentos de forma uniforme, eliminando if/switch . Exemplo: Uma interface Pagamento com implementações CartaoCredito , PayPal , Boleto . O sistema chama pagamento.realizar() sem saber qual é. Aplicação: Torna o código extensível e limpo. Invenção Pura: Crie classes artificiais que não representam conceitos do domínio para manter a coesão. Exemplo: PedidoRepository (para persistência) ou CalculadoraDeFrete (serviço externo). Aplicação: Separa responsabilidades técnicas das regras de negócio. Indireção: Introduza um intermediário entre dois objetos para reduzir acoplamento. Exemplo: Um Proxy para acessar um objeto remoto, ou um Adapter para integrar uma biblioteca de terceiros. Aplicação: Isola o cliente de detalhes de implementação ou de mudanças externas. Variações Protegidas: Identifique pontos que podem variar (como banco de dados, provedor de pagamento) e isole-os com interfaces. ASP.NET https://asp.net/ Exemplo: Definir uma interface Repositorio e ter implementações para MySQL, MongoDB, etc. Aplicação: Permite trocar a implementação sem afetar o resto do sistema. 🏭 PADRÕES GOF DE CRIAÇÃO Tratam da criação de objetos de forma flexível. Factory Method: Use quando uma classe não pode antecipar a classe de objetos que deve criar. Exemplo: Um framework de UI tem uma classe Dialog que cria botões. As subclasses ( WindowsDialog , LinuxDialog ) implementam o método criarBotao() para retornar o botão específico da plataforma. Aplicação: Útil em frameworks e bibliotecas. Abstract Factory: Use para criar famílias de objetos relacionados sem especificar as classes concretas. Exemplo: Um sistema de integração com diferentes bancos de dados pode ter FabricaDeConexoes que cria Conexao e Comando específicos para cada banco. Aplicação: Quando o sistema precisa ser configurado para diferentes ambientes (ex: produção vs teste). Builder: Use para construir objetos complexos passo a passo, permitindo diferentes representações. Exemplo: Construir uma query SQL, um documento HTML, ou um objeto Pessoa com muitos parâmetros opcionais. O StringBuilder em Java/C# é um exemplo. Aplicação: Evita construtores com muitos parâmetros e melhora a legibilidade. Prototype: Use quando a criação de um objeto é mais cara do que cloná-lo, ou quando você quer evitar subclasses. Exemplo: Em jogos, clonar um inimigo padrão para criar variações (com cores diferentes) em vez de instanciar do zero. Aplicação: Útil quando o sistema deve ser independente de como seus objetos são criados. Singleton: Garante uma única instância de uma classe e fornece um ponto global de acesso. Exemplo: Gerenciador de conexão com banco de dados, logger, cache. Aplicação: Use com moderação, pois pode dificultar testes e criar acoplamento global. 🧱 PADRÕES GOF ESTRUTURAIS Tratam da composição de classes e objetos para formar estruturas maiores. Adapter: Permite que classes com interfaces incompatíveis trabalhem juntas. Exemplo: Você tem uma biblioteca de pagamento com uma interface PagamentoAntigo , mas seu sistema espera NovoPagamento . Um adaptador traduz as chamadas. Aplicação: Integração de sistemas legados ou bibliotecas de terceiros. Bridge: Separa uma abstração da sua implementação, permitindo que ambas variem independentemente. Exemplo: Controles remotos (abstração) e dispositivos (implementação). Um controle pode operar TV, rádio, etc., sem conhecer os detalhes. Aplicação: Evita explosão de classes quando há múltiplas dimensões de variação. Composite: Permite tratar objetos individuais e composições de objetos de maneira uniforme. Exemplo: Sistemas de arquivos: pastas e arquivos. Uma operação tamanho() em uma pasta retorna a soma dos tamanhos dos filhos. Aplicação: Estruturas hierárquicas como menus, árvores, organização de departamentos. Decorator: Adiciona responsabilidades a objetos dinamicamente, sem alterar sua classe. Exemplo: Em Java I/O, você pode decorar um FileInputStream com BufferedInputStream e depois com ZipInputStream . Aplicação: Quando você precisa adicionar funcionalidades de forma flexível e combinável (ex: criptografia, compressão, log). Facade: Fornece uma interface simplificada para um subsistema complexo. Exemplo: Uma classe Computador que oferece métodos ligar() e desligar() , ocultando a complexidade de inicializar CPU, memória, discos, etc. Aplicação: Reduz acoplamento e simplifica o uso de bibliotecas complexas. Flyweight: Compartilha objetos para economizar memória, especialmente quando muitos objetos são semelhantes. Exemplo: Em um processador de texto, cada caractere pode ser um objeto flyweight com a fonte e estilo compartilhados, e a posição é extrínseca. Aplicação: Jogos com muitos objetos (balas, árvores) ou sistemas com grande quantidade de dados imutáveis. Proxy: Controla o acesso a um objeto, podendo adicionar funcionalidades como lazy loading, controle de acesso, log, etc. Exemplo: Um Proxy de imagem que carrega a imagem real apenas quando ela for exibida. Aplicação: Acesso remoto (RMI), objetos pesados, segurança. 🧠 PADRÕES GOF COMPORTAMENTAIS Tratam de algoritmos e responsabilidades entre objetos. Chain of Responsibility: Permite que uma requisição seja passada por uma cadeia de objetos até que um a trate. Exemplo: Sistemas de suporte: um atendente, se não resolver, passa para o supervisor, depois para o gerente. Aplicação: Filtros em frameworks web, tratamento de exceções, validações em cascata. Command: Encapsula uma requisição como um objeto, permitindo parametrizar, enfileirar e desfazer operações. Exemplo: Botões de uma interface gráfica: cada botão tem um comando associado (salvar, imprimir). Aplicação: Undo/redo, transações, tarefas agendadas. Iterator: Fornece uma maneira de acessar elementos de uma coleção sequencialmente sem expor sua estrutura interna. Exemplo: O foreach em várias linguagens usa um iterador por baixo. Aplicação: Qualquer estrutura de dados que precise ser percorrida. Mediator: Centraliza a comunicação entre objetos, reduzindo acoplamento. Exemplo: Em um chat, o servidor (mediador) recebe mensagens de um usuário e as encaminha para os outros. Aplicação: Interfaces gráficas com muitos componentes que interagem (ex: um campo de texto que atualiza outros). Memento: Captura e externaliza o estado de um objeto para quepossa ser restaurado posteriormente. Exemplo: O "Ctrl+Z" em editores: o estado do documento é salvo antes de cada operação. Aplicação: Checkpoints, undo/redo, histórico. Observer: Define uma dependência um-para-muitos entre objetos, de modo que quando um muda, todos os dependentes são notificados. Exemplo: Planilhas: um gráfico é atualizado automaticamente quando os dados mudam. Aplicação: Eventos em UI, sistemas de notificação, MVC (onde a view observa o modelo). State: Permite que um objeto altere seu comportamento quando seu estado interno muda. Exemplo: Uma máquina de vendas: os comportamentos de "inserir moeda", "selecionar produto" dependem do estado (sem moeda, com moeda, produto entregue). Aplicação: Controle de fluxo de pedidos, jogos (estados de personagem). Strategy: Define uma família de algoritmos, encapsula cada um e os torna intercambiáveis. Exemplo: Um sistema de cálculo de frete pode ter estratégias: FreteNormal , FreteExpresso , FreteInternacional . Aplicação: Quando você tem várias maneiras de fazer a mesma coisa e quer poder escolher em tempo de execução. Template Method: Define o esqueleto de um algoritmo em uma operação, deixando alguns passos para as subclasses. Exemplo: Um método prepararBebida() que chama ferverAgua() , adicionarIngrediente() , servir() . Subclasses como Cafe e Cha implementam adicionarIngrediente() . Aplicação: Frameworks, onde o fluxo principal é fixo, mas partes podem ser customizadas. Visitor: Permite adicionar novas operações a uma hierarquia de objetos sem modificar as classes. Exemplo: Em um compilador, você pode ter uma árvore sintática e visitantes para análise semântica, geração de código, etc. Aplicação: Quando você tem muitas operações distintas sobre uma estrutura estável. Interpreter: Dada uma linguagem, define uma representação para sua gramática e um interpretador. Exemplo: Calculadoras de expressões, processamento de linguagens de script simples. Aplicação: Útil para linguagens de domínio específico (DSL) pequenas. 🖥 TECNOLOGIAS JPA E JEE (Mais específicas de Java) JPA (Java Persistence API): Padroniza o mapeamento objeto-relacional. Use quando você precisa persistir objetos em banco de dados relacionais sem escrever SQL manualmente. Exemplo: Uma classe Produto com anotações @Entity , e o framework gera as queries. EJB (Enterprise JavaBeans): Componentes server-side para lógica de negócio em aplicações corporativas. Oferecem transações, segurança, escalabilidade. Exemplo: Um @Stateless EJB que calcula impostos, usado por múltiplos clientes. MVC (Model-View-Controller): Arquitetura que separa dados (Model), interface (View) e controle (Controller). Exemplo: Aplicações web: Model (classes de domínio + DAO), Controller (Servlets ou EJBs), View (JSP). Front Controller: Um único servlet que recebe todas as requisições e as direciona para ações específicas. Exemplo: Frameworks como Spring MVC têm um DispatcherServlet que faz isso. Mesmo sem Java, você encontrará equivalentes em outras tecnologias: JPA ~ Hibernate (em Java), Entity Framework (C#), SQLAlchemy (Python). EJB ~ Spring (Java), ou serviços em outras linguagens. MVC é universal: Django (Python), MVC (C#), Laravel (PHP). Resumindo: os padrões são soluções para problemas comuns de design. Aprender a identificar o problema é mais importante do que a implementação em si. Depois que você entende o padrão, pode aplicá-lo em qualquer linguagem. ASP.NET https://asp.net/