Guia Extra: Engenharia de Software e Modelagem UML • Bloco 3: Modelagem Estrutural


🗺️ Mapa Conceitual do Capítulo

flowchart TD
    ESTR["Modelagem Estrutural Complementar (UML 2.5)"] --> DO["Diagrama de Objetos (Object Diagram)\nFotografia Instantânea da Memória em Execução"]
    ESTR --> DP["Diagrama de Pacotes (Package Diagram)\nArquitetura Modular, Namespaces e Princípios de Métricas"]

    subgraph OBJ_CORE["Anatomia da Instância Concreta"]
        DO --> INST["Instâncias Sublinhadas: nomeObjeto : NomeClasse"]
        DO --> SLOTS["Slots de Valores: atributo = valor_concreto"]
        DO --> LINKS["Vínculos (Links): Instâncias de Associações (Sem Multiplicidade)"]
    end

    subgraph PACK_CORE["Princípios de Design de Pacotes (Robert C. Martin)"]
        DP --> METR_COESAO["Coesão: REP (Equivalência de Release) · CCP (Fechamento Comum) · CRP (Reuso Comum)"]
        DP --> METR_ACOPL["Acoplamento: ADP (Acíclico) · SDP (Dependências Estáveis) · SAP (Abstrações Estáveis)"]
        DP --> MAIN_SEQ["Métrica da Sequência Principal: Distância D = |A + I - 1|"]
    end

    style ESTR fill:#ede7f6,stroke:#512da8,stroke-width:2px
    style DO fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
    style DP fill:#fff3e0,stroke:#ff9800,stroke-width:2px
    style OBJ_CORE fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
    style PACK_CORE fill:#fce4ec,stroke:#e91e63,stroke-width:2px

📸 1. O Diagrama de Objetos: A “Fotografia” em Tempo de Execução

Enquanto o Diagrama de Classes descreve todos os estados hipotéticos e a estrutura estática que o código pode assumir, o Diagrama de Objetos captura um snapshot (fotografia congelada) das instâncias reais alocadas na memória heap em um determinado milissegundo de execução.

Notação Formal da Instância e Slots

  • Nome do Objeto (Sublinhado Obrigatório):
    • Objeto Nomeado: ana : Leitor (Indica a instância “ana” da classe “Leitor”).
    • Objeto Anônimo: : Exemplar (Indica uma instância qualquer de “Exemplar”).
  • Slots de Atributos: Uma lista com os valores pontuais dos campos naquele instante (matricula = "2026-A", saldoMulta = 0.00).
  • Vínculos (Links): As linhas que conectam instâncias representam instâncias físicas de associações.
    • ⚠️ Atenção: Em um Diagrama de Objetos, é proibido grafar multiplicidades (como * ou 1..*). O vínculo é concreto: conecta uma instância específica a outra.
graph LR
    subgraph SNAPSHOT["Snapshot da Memória no Instante T1"]
        O1["<u>leitorAna : Leitor</u><br/>nome = 'Ana Silva'<br/>limiteAtivo = 3"]
        O2["<u>emp01 : Emprestimo</u><br/>dataRetirada = '2026-09-01'<br/>status = 'ATRASADO'"]
        O3["<u>ex10 : Exemplar</u><br/>codigoBarras = 'BR-9821'"]

        O1 ---|"link: tomador"| O2
        O2 ---|"link: item"| O3
    end

Aplicações Arquiteturais do Diagrama de Objetos

  1. Validação de Casos de Borda do Diagrama de Classes: Se ao tentar modelar um caso real da empresa (como um empréstimo com devolução parcial e multa renegociada) os objetos não conseguirem se conectar sem violar as regras da classe, o modelo de classes está defeituoso.
  2. Criação de Fixtures de Testes Automatizados: O diagrama de objetos serve como especificação direta para a montagem de dados de teste (mocks e dados seminais de banco de dados).

📦 2. Diagrama de Pacotes e Estratégias de Modularização

O Diagrama de Pacotes gerencia a complexidade de grandes sistemas de software através da organização hierárquica de elementos em subsistemas lógicos e espaços de nomes (namespaces). Graficamente, é representado pelo símbolo clássico da “pasta de arquivo com aba”.

Estereótipos de Dependência entre Pacotes

  • «import»: Permite que os elementos públicos do pacote de destino sejam referenciados no pacote de origem sem a necessidade de prefixar o namespace completo.
  • «access»: Importa os elementos privados exclusivamente para o namespace local do pacote.

Estratégias de Empacotamento

  1. Package by Layer (Por Camada Técnica): Agrupa por responsabilidade técnica (controllers, services, repositories). Comum em sistemas menores, mas dilui o domínio do negócio em pastas dispersas.
  2. Package by Feature / Domain (Por Funcionalidade / Domínio): Recomendado pela engenharia moderna e pelo DDD. Cria módulos coesos e autocontidos (pedidos, catalogo, faturamento). Cada pacote contém internamente seus próprios handlers, entidades e repositórios.

🔁 3. As Métricas e Princípios de Pacotes de Robert C. Martin

No clássico Agile Software Development: Principles, Patterns, and Practices, Robert C. Martin (“Uncle Bob”) definiu seis princípios de engenharia para governar o design de pacotes e componentes:

Princípios de Acoplamento de Pacotes (Package Coupling)

graph TD
    P1["Pacote A (Alta Estabilidade: Interfaces Core)"]
    P2["Pacote B (Camada de Aplicação)"]
    P3["Pacote C (Camada de UI / Volátil)"]

    P3 -->|"Depende de"| P2
    P2 -->|"Depende de"| P1

    style P1 fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    style P2 fill:#fffde7,stroke:#fbc02d,stroke-width:2px
    style P3 fill:#ffebee,stroke:#e53935,stroke-width:2px
  1. ADP - Acyclic Dependencies Principle (Princípio das Dependências Acíclicas):
    • O grafo de dependências entre pacotes não pode conter ciclos ($A \rightarrow B \rightarrow C \rightarrow A$). Ciclos criam o chamado “Morning After Syndrome”, onde uma alteração simples em um pacote quebra compilações em cadeia por todo o projeto.
  2. SDP - Stable Dependencies Principle (Princípio das Dependências Estáveis):
    • As dependências devem apontar sempre na direção da estabilidade. Um pacote instável (sujeito a mudanças constantes de requisitos) deve depender de pacotes estáveis (difíceis de mudar porque muitos dependem deles).
  3. SAP - Stable Abstractions Principle (Princípio das Abstrações Estáveis):
    • Quanto mais estável for um pacote, mais abstrato ele deve ser (composto por interfaces e classes puramente abstratas). Pacotes instáveis devem ser concretos para facilitar mutações.

A Métrica da Distância da Sequência Principal

  • Eferência ($Ce$): Número de classes fora do pacote das quais as classes internas dependem.
  • Aferência ($Ca$): Número de classes fora do pacote que dependem das classes internas.
  • Instabilidade ($I$): \(I = \frac{Ce}{Ca + Ce} \quad (0 = \text{Ultra-Estável}, \ 1 = \text{Totalmente Instável})\)
  • Abstração ($A$): Razão entre o número de interfaces/classes abstratas e o total de classes do pacote ($0 \le A \le 1$).
  • Distância Normalizada ($D$): \(D = |A + I - 1|\) Um pacote saudável situa-se exatamente sobre a Sequência Principal ($D \approx 0$). Pacotes com $A \approx 0$ e $I \approx 0$ caem na temida Zona da Dor (Zone of Pain: código concreto que não pode mudar porque todos dependem dele), enquanto pacotes com $A \approx 1$ e $I \approx 1$ caem na Zona da Inutilidade (Zone of Uselessness: interfaces abstratas das quais ninguém depende).