Pular para conteúdo

Aula 19 - Modelagem Orientada a Objetos com Design Patterns UML 📐

Objetivo Pedagógico

Objetivo: Expressar visualmente os padrões clássicos de projeto (GoF - Gang of Four) em Diagramas de Classes UML avançados: Strategy, Observer, Factory Method, Decorator e Adapter, compreendendo as convenções de multiplicidade e herança versus composição.


📑 1. Fundamentos Teóricos & Análise Técnica

O Diagrama de Classes é o diagrama mais universal da UML, fornecendo uma descrição estrutural formal das classes, interfaces, atributos, operações e relacionamentos que compõem o sistema.

A aplicação de Design Patterns (Padrões de Projeto GoF) encontra na UML o veículo perfeito de expressão: 1. Convenções Rigorosas da UML de Classes: - Visibilidade: + Público, - Privado, # Protegido, ~ Pacote. - Relacionamentos Estruturais: - Herança / Generalização: Linha sólida com seta triangular vazia apontando para a superclasse. - Realização de Interface: Linha tracejada com seta triangular vazia apontando para a interface. - Associação Simples: Linha sólida representando conhecimento mútuo ou dependência estrutural. - Agregação Fraca: Linha sólida com losango vazio na ponta do todo (a parte pode existir sem o todo). - Composição Forte: Linha sólida com losango preenchido na ponta do todo (a destruição do todo destrói a parte). 2. Modelagem de Padrões Clássicos: - Strategy Pattern: Substitui cadeias imensas de if/else delegando algoritmos a uma interface comum. - Observer Pattern: Suporte a desacoplamento de eventos através de um Subject mantendo lista de observadores tipados. - Decorator Pattern: Extensão dinâmica de funcionalidades sem herança múltipla, agregando a interface que ele próprio implementa.

📐 Arquitetura Conceitual & Diagrama de Fluxo

classDiagram
    class PaymentStrategy {
        <<interface>>
        +pay(amount: float) bool
    }
    class CreditCardPayment {
        -cardNumber: string
        -cvv: string
        +pay(amount: float) bool
    }
    class PixPayment {
        -pixKey: string
        +pay(amount: float) bool
    }
    class PaymentContext {
        -strategy: PaymentStrategy
        +setStrategy(s: PaymentStrategy) void
        +executePayment(amount: float) bool
    }

    PaymentStrategy <|.. CreditCardPayment : Realização
    PaymentStrategy <|.. PixPayment : Realização
    PaymentContext o--> PaymentStrategy : Agregação (Composição)

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Prefira Composição à Herança: O padrão Strategy ilustrado utiliza composição flexível em runtime em vez de hierarquias rígidas de classes. - Princípio Aberto-Fechado (OCP): Novas estratégias de pagamento podem ser criadas sem alterar uma única linha de código do PaymentContext. - Notação Precisa de Visibilidade: Uso estrito de - para proteger estados internos de dados sensíveis como números de cartão de crédito. - Polimorfismo Baseado em Interfaces: Garantia de que o cliente converse exclusivamente com contratos abstratos.


🛠️ 2. Implementação Prática em UML Estrutural, Design Patterns GoF e Modelagem de Classes

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// observer_decorator_patterns.mermaid (Modelagem UML dos Padrões Observer e Decorator)
classDiagram
    %% Padrão Observer
    class Subject {
        <<interface>>
        +attach(observer: Observer) void
        +detach(observer: Observer) void
        +notify() void
    }
    class ConcreteSubject {
        -state: int
        -observers: List~Observer~
        +getState() int
        +setState(state: int) void
    }
    class Observer {
        <<interface>>
        +update(state: int) void
    }
    class ConcreteObserverA {
        +update(state: int) void
    }
    class ConcreteObserverB {
        +update(state: int) void
    }

    Subject <|.. ConcreteSubject
    Observer <|.. ConcreteObserverA
    Observer <|.. ConcreteObserverB
    ConcreteSubject o--> Observer : Notifica múltiplos

💡 Análise Passo a Passo do Código

  1. Uso do Estereótipo <<interface>>: Identifica claramente os contratos abstratos do padrão Observer.
  2. Agregação Múltipla (List~Observer~): Representa a lista dinâmica de ouvintes desacoplados do estado concreto.
  3. Relação de Realização (<|..): Modela a implementação do método update() pelas classes especializadas de notificação.

🎯 3. Próximos Passos & Sequência Didática