Guia Extra: Engenharia de Software e Modelagem UML • Bloco 2: Requisitos e Processos em Modelo • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 8.1 — Final de Atividade ou Final de Fluxo?

Contexto: No fechamento do dia, um dos ramos paralelos envia lembretes; se não houver lembretes a enviar, aquele ramo termina ali.

Requisitos de Execução:

  1. Diga qual nó final usar no ramo sem lembretes e explique o que aconteceria com o outro nó final.
  2. Explique a diferença entre junção (merge) e join.

Resultado Esperado

Duas respostas curtas com a justificativa.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_08_1_SeuNome.md
  2. Envie na tarefa: Atividade Cap 08 - Diagrama de Atividades: Ações, Decisões, Concorrência e Raias
🔑 Gabarito de Código & Solução Comentada
  1. Final de fluxo (círculo com X): encerra só aquele ramo. Um final de atividade encerraria toda a atividade, interrompendo as multas e as reservas que ainda estão rodando nos outros ramos.
  2. Junção (merge) reúne caminhos alternativos e deixa passar a primeira ficha que chegar; join reúne caminhos paralelos e espera todas as fichas.

🎯 Nível 2: Prática

Problema 8.2 — Atividade da Renovação Online

Contexto: Regras da renovação: não pode renovar se o empréstimo venceu, se há reserva do título ou se já renovou 2 vezes. Se puder, o vencimento avança 14 dias e o leitor recebe e-mail.

Requisitos de Execução:

  1. Desenhe o diagrama de atividades com raias Leitor e SGB.
  2. Use guardas mutuamente exclusivas e [else].

Resultado Esperado

Um diagrama com 3 decisões (ou uma decisão com 4 saídas) e um único final de atividade.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_08_2_SeuNome.md
  2. Envie na tarefa: Atividade Cap 08 - Diagrama de Atividades: Ações, Decisões, Concorrência e Raias
🔑 Gabarito de Código & Solução Comentada
flowchart TB
    subgraph LEI["Leitor"]
        I(("●")) --> P["Pedir renovação"]
        MSG["Ler mensagem"] --> F(("◉"))
    end
    subgraph SGB["SGB"]
        P --> D1{"vencido?"}
        D1 -->|"[sim]"| N1["Negar: devolver e pagar multa"]
        D1 -->|"[else]"| D2{"há reserva?"}
        D2 -->|"[sim]"| N2["Negar: há fila"]
        D2 -->|"[else]"| D3{"renovações >= 2?"}
        D3 -->|"[sim]"| N3["Negar: limite atingido"]
        D3 -->|"[else]"| OK["Avançar vencimento em 14 dias"]
        OK --> EM["Enviar e-mail de confirmação"]
        N1 --> MSG
        N2 --> MSG
        N3 --> MSG
        EM --> MSG
    end

🎯 Nível 3: Integração

Problema 8.3 — Do Caso de Uso ao Diagrama e de Volta

Contexto: Use a especificação do UC02 (Emprestar exemplar) do Capítulo 06.

Requisitos de Execução:

  1. Desenhe o diagrama de atividades do UC02 com os fluxos alternativos 2a, 2b, 4a e 4b.
  2. Aponte quais ações cruzam raias e que interface cada cruzamento indica.

Resultado Esperado

Diagrama com raias Bibliotecária e SGB e uma lista de interfaces.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_08_3_SeuNome.md
  2. Envie na tarefa: Atividade Cap 08 - Diagrama de Atividades: Ações, Decisões, Concorrência e Raias
🔑 Gabarito de Código & Solução Comentada
flowchart TB
    subgraph BIB["Bibliotecária"]
        I(("●")) --> CL["Informar código do leitor"]
        CX["Informar código do exemplar"]
        CF["Confirmar empréstimo"]
        AV["Ver mensagem de recusa"] --> FR(("◉"))
    end
    subgraph SGB["SGB"]
        CL --> VP["Verificar pendências"]
        VP --> D1{"pendência?"}
        D1 -->|"[multa em aberto]"| AV
        D1 -->|"[3 empréstimos]"| AV
        D1 -->|"[else]"| CX
        CX --> D2{"exemplar reservado por outro?"}
        D2 -->|"[sim]"| CX
        D2 -->|"[else]"| D3{"professor?"}
        D3 -->|"[sim]"| P21["Prazo de 21 dias"]
        D3 -->|"[else]"| P14["Prazo de 14 dias"]
        P21 --> M{" "}
        P14 --> M
        M --> CF
        CF --> REG["Registrar e enviar comprovante"] --> FS(("◉"))
    end

Cruzamentos de raia: informar código do leitor e do exemplar (tela de leitura com leitor de código de barras → endpoint GET /leitores/{id}/pendencias); confirmar (botão → POST /emprestimos); mensagem de recusa (resposta da API exibida na tela).


🎯 Nível 4: Desafio

Problema 8.4 — Executor de Atividades com Decisões

Contexto: Um diagrama de atividades pode ser interpretado: cada nó é uma ação ou uma decisão com guardas.

Requisitos de Execução:

  1. Represente a renovação do Problema 8.2 como um dicionário de nós; decisões guardam uma função de guarda e os destinos sim/nao.
  2. Escreva uma função executar(emprestimo) que percorra o grafo a partir do nó inicial e devolva a lista de ações executadas.
  3. Teste com 4 empréstimos: um que renova e três negados por motivos diferentes.

Resultado Esperado

Para cada empréstimo, a trilha de ações executadas até o final.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_08_4_SeuNome.md
  2. Envie na tarefa: Atividade Cap 08 - Diagrama de Atividades: Ações, Decisões, Concorrência e Raias
🔑 Gabarito de Código & Solução Comentada
# executor_atividades.py
NOS = {
    "inicio": ("acao", "pedir renovação", "d_vencido"),
    "d_vencido": ("decisao", lambda e: e["vencido"], "n_vencido", "d_reserva"),
    "d_reserva": ("decisao", lambda e: e["reserva"], "n_reserva", "d_limite"),
    "d_limite": ("decisao", lambda e: e["renovacoes"] >= 2, "n_limite", "renovar"),
    "renovar": ("acao", "avançar vencimento 14 dias", "email"),
    "email": ("acao", "enviar e-mail", "fim"),
    "n_vencido": ("acao", "negar: vencido", "fim"),
    "n_reserva": ("acao", "negar: há fila", "fim"),
    "n_limite": ("acao", "negar: limite", "fim"),
    "fim": ("final",),
}

def executar(emprestimo: dict) -> list[str]:
    trilha, atual = [], "inicio"
    while NOS[atual][0] != "final":
        no = NOS[atual]
        if no[0] == "acao":
            trilha.append(no[1])
            atual = no[2]
        else:
            atual = no[2] if no[1](emprestimo) else no[3]
    return trilha

CASOS = {
    "renova": {"vencido": False, "reserva": False, "renovacoes": 0},
    "vencido": {"vencido": True, "reserva": False, "renovacoes": 0},
    "com fila": {"vencido": False, "reserva": True, "renovacoes": 1},
    "limite": {"vencido": False, "reserva": False, "renovacoes": 2},
}
for nome, e in CASOS.items():
    print(f"{nome:8}: {' > '.join(executar(e))}")

Saída:

renova  : pedir renovação > avançar vencimento 14 dias > enviar e-mail
vencido : pedir renovação > negar: vencido
com fila: pedir renovação > negar: há fila
limite  : pedir renovação > negar: limite

Comentário: é assim, em escala muito maior, que motores de workflow executam modelos. A ordem das decisões importa: um empréstimo vencido e com fila é negado por “vencido”, porque essa guarda vem primeiro.