Guia Extra: Engenharia de Software e Modelagem UML • Bloco 4: Comportamento e Arquitetura • Demonstrações Práticas


🧩 Exemplo 1: Componentes do SGB (Caixa-Preta)

flowchart LR
    subgraph WEB["«component» PortalWeb"]
    end
    subgraph CIR["«component» Circulacao"]
    end
    subgraph ACV["«component» Acervo"]
    end
    subgraph NOT["«component» Notificacao"]
    end
    I1(("IEmprestimos")) --- CIR
    I2(("IConsultaAcervo")) --- ACV
    I3(("INotificador")) --- NOT
    WEB -. "requer" .-> I1
    WEB -. "requer" .-> I2
    CIR -. "requer" .-> I2
    CIR -. "requer" .-> I3

Cada círculo é uma interface fornecida; as setas tracejadas saem de quem a requer. O Circulacao não sabe se as notificações vão por e-mail ou SMS.


🧬 Exemplo 2: Estrutura Composta do Componente Circulacao

flowchart LR
    P1["▪ porta IEmprestimos"] --> CTRL["controlador : ServicoEmprestimo"]
    subgraph CIR["Circulacao"]
        CTRL --> REG["regras : PoliticaDeEmprestimo"]
        CTRL --> REP["repositorio : RepositorioEmprestimos"]
        CTRL --> PUB["publicador : PublicadorEventos"]
    end
    PUB --> P2["▪ porta INotificador"]

A porta de entrada delega para o controlador; a porta de saída expõe a interface requerida.


🖥️ Exemplo 3: Implantação do SGB

flowchart LR
    subgraph NAV["«device» Computador do balcão"]
        subgraph BR["«executionEnvironment» Navegador"]
            A1["«artifact» portal-web (JS)"]
        end
    end
    subgraph SRV["«device» Servidor da prefeitura (Linux)"]
        subgraph DK["«executionEnvironment» Docker"]
            A2["«artifact» sgb-api:1.4 (imagem)"]
            A3["«artifact» postgres:16"]
        end
    end
    subgraph EXT["«device» Provedor de e-mail"]
        A4["serviço SMTP"]
    end
    A1 -- "HTTPS" --> A2
    A2 -- "TCP 5432 (SQL)" --> A3
    A2 -- "SMTP/TLS" --> A4

🐍 Exemplo 4: Interfaces Fornecidas e Requeridas em Código

# componentes.py
from typing import Protocol

class INotificador(Protocol):                      # interface
    def enviar(self, para: str, texto: str) -> str: ...

class NotificacaoEmail:                            # componente que FORNECE INotificador
    def enviar(self, para: str, texto: str) -> str:
        return f"e-mail para {para}: {texto}"

class Circulacao:                                  # componente que REQUER INotificador
    def __init__(self, notificador: INotificador):
        self._notificador = notificador

    def emprestar(self, leitor: str, titulo: str) -> str:
        return self._notificador.enviar(leitor, f"empréstimo de '{titulo}' registrado")

# "raiz de composição": o conector de montagem entre os componentes
circulacao = Circulacao(notificador=NotificacaoEmail())
print(circulacao.emprestar("ana@exemplo.org", "Vidas Secas"))

Saída:

e-mail para ana@exemplo.org: empréstimo de 'Vidas Secas' registrado