🔄 ATIVIDADE 12: DIAGRAMA DE MÁQUINA DE ESTADOS (UML)
Para realizar este laboratório com sucesso, certifique-se de ter compreendido os conceitos apresentados no:
👉 CAPÍTULO 12: DIAGRAMA DE CLASSES (CONCEITOS)
Bem-vindo a mais uma etapa prática do seu treinamento em Engenharia de Software. Na atividade anterior, você aprendeu sobre processos e fluxos lógicos. Hoje, nosso foco muda para o ciclo de vida de uma entidade do sistema. Você aprenderá como modelar os Estados pelos quais um dado transiciona, garantindo que o software nunca entre em inconsistência lógica. 🛡️🧩
🎯 Objetivos de Aprendizagem do Laboratório
Ao final deste laboratório prático (estimativa: 4 horas presenciais / autoguiadas), você será capaz de:
- Identificar entidades de negócio com ciclos de vida complexos.
- Modelar os Estados estáveis de um objeto no sistema.
- Mapear Eventos Gatilho (Triggers) que provocam a transição entre estados.
- Aplicar Condições de Guarda (Guards) para proteção lógica contra transições inválidas.
🏢 O Cenário Prático (Seu Desafio)
Na TecProExpress, tivemos um incidente grave de banco de dados: um cliente de suporte ligou reclamando que a sua entrega apareceu no sistema como "Entregue com Sucesso", mas o motorista ainda nem havia saído com o caminhão do centro de distribuição!
Ao analisar o código, a equipe técnica descobriu que não havia validação de regras de negócios. Um motorista distraído clicou no botão "Confirmar Entrega" na tela errada de um pacote que ainda estava no estado de triagem físico!
"Seu desafio como Arquiteto de Software é desenhar o Diagrama de Máquina de Estados para a entidade Entrega. Você deve blindar o sistema, definindo as regras exatas de como um pacote muda de estado (ex: de Pendente para Em Rota) e quais validações (guardas) impedem que um pacote seja marcado como Entregue antes de ser despachado."
🧠 Fundamentos: A Teoria Traduzida
Enquanto o Diagrama de Atividades mostra o fluxo das ações de um processo, o Diagrama de Máquina de Estados foca em um único objeto do início ao fim da sua existência.
Elementos Chave:
- Estado Inicial (Círculo Preto): O ponto de criação do objeto.
- Estado (Retângulo Arredondado): Uma condição estável na vida do objeto onde ele aguarda um evento (Ex:
PENDENTE,EM_ROTA,ENTREGUE). - Transição (Seta Direcionada): A mudança de um estado para o outro.
- Evento Gatilho (Trigger): A ação que dispara a transição (Ex:
despacharPacote()). - Condição de Guarda (Guard - entre colchetes
[...]): Uma regra que precisa ser verdadeira para a transição acontecer. (Ex:[motorista_no_local == true]).
📊 Visualizando a Lógica
Condição Guarda: Pense na guarda como um segurança de boate. A transição quer acontecer, mas o segurança impede se a condição não for atendida!
📖 Exemplo Guiado
Abaixo, veja o mapeamento de transição para o ciclo de vida do pacote da TecProExpress.
| Estado Origem | Evento Gatilho | Condição Guarda | Estado Destino |
|---|---|---|---|
PENDENTE | despachar() | [motorista_associado != null] | EM_ROTA |
EM_ROTA | confirmarEntrega() | [distancia_gps_cliente < 100m] | ENTREGUE |
EM_ROTA | cancelarPedido() | [motivo != null] | CANCELADO |
🛠️ Regra UML em Sintaxe Padrão:
A sintaxe formal gravada na seta da transição segue o padrão:
Evento [Guarda] / Ação executada
- Exemplo:
confirmarEntrega [comprovanteAnexado] / notificarCliente()
stateDiagram-v2
state "Pendente de Coleta" as P
state "Em Rota de Entrega" as ER
state "Cancelado" as C
state "Entregue" as E
[*] --> P
P --> ER : atribuirMotorista [motorista_ativo == true]
ER --> E : confirmarEntrega [gps_ok == true] / enviarSMS()
ER --> C : cancelar [cliente_solicitou] / estornarCartao()
C --> [*]
E --> [*]
🔍 Detalhamento do Processo:
- Note a guarda
[gps_ok == true]. Se o aplicativo do motorista não coletar a coordenada geográfica a menos de 100 metros da casa do cliente, o sistema bloqueia a mudança para o estadoEntregue, evitando fraudes ou cliques acidentais!
🛠️ Prática Obrigatória 1: A Máquina de Estados
Cenário: O projeto semestral da sua equipe.
- Selecione a entidade mais crítica do seu sistema que possui vários status (Ex:
Pedidoem um e-commerce,Agendamentoem uma clínica,Vagaem um estacionamento). - Mapeie pelo menos 4 estados distintos para essa entidade.
- Defina claramente os Eventos Gatilho em cada seta de transição.
- Adicione pelo menos 2 Condições de Guarda entre colchetes
[...]para blindar transições perigosas.
🏁 Resultado Esperado (Para sua Referência)
Uma imagem (PNG/JPG) do diagrama de máquina de estados UML modelado de forma organizada, exibindo a trajetória completa da entidade do estado inicial ao final.
💻 Máquina de Estados Finita (State Pattern) em Python
Para validar as transições de ciclo de vida com condições de guarda blindadas:
# maquina_estados.py
from enum import Enum
class StatusEntrega(Enum):
PENDENTE = "PENDENTE"
EM_ROTA = "EM_ROTA"
ENTREGUE = "ENTREGUE"
CANCELADO = "CANCELADO"
class PacoteFSM:
def __init__(self, cod_rastreio: str) -> None:
self.cod_rastreio = cod_rastreio
self.estado_atual = StatusEntrega.PENDENTE
def despachar(self, motorista_ativo: bool) -> None:
if self.estado_atual != StatusEntrega.PENDENTE:
raise ValueError(f"Não é possível despachar pacote no estado {self.estado_atual.value}")
if not motorista_ativo: # Condição de Guarda [motorista_ativo == true]
raise PermissionError("Guarda Violada: Nenhum motorista ativo atribuído.")
self.estado_atual = StatusEntrega.EM_ROTA
print(f"🚚 [{self.cod_rastreio}] Transição de Estado: PENDENTE -> EM_ROTA")
def confirmar_entrega(self, distancia_metros: float) -> None:
if self.estado_atual != StatusEntrega.EM_ROTA:
raise ValueError("Apenas pacotes em rota podem ser confirmados como entregues.")
if distancia_metros > 100.0: # Condição de Guarda [gps_ok == true]
raise ValueError(f"Guarda Violada: Motorista está a {distancia_metros}m do local (máximo permitido: 100m).")
self.estado_atual = StatusEntrega.ENTREGUE
print(f"✅ [{self.cod_rastreio}] Transição de Estado: EM_ROTA -> ENTREGUE (GPS Validado a {distancia_metros}m)")
if __name__ == "__main__":
print("=" * 65)
print("🚦 MÁQUINA DE ESTADOS FINITA (FSM / STATE PATTERN) - TECPROEXPRESS")
print("=" * 65)
fsm = PacoteFSM("BR-4401")
print(f"Estado Inicial: {fsm.estado_atual.value}")
fsm.despachar(motorista_ativo=True)
fsm.confirmar_entrega(distancia_metros=25.0)
print(f"Estado Final Consolidado: {fsm.estado_atual.value}")
print("=" * 65)
🖥️ Saída Esperada no Terminal:
=================================================================
🚦 MÁQUINA DE ESTADOS FINITA (FSM / STATE PATTERN) - TECPROEXPRESS
=================================================================
Estado Inicial: PENDENTE
🚚 [BR-4401] Transição de Estado: PENDENTE -> EM_ROTA
✅ [BR-4401] Transição de Estado: EM_ROTA -> ENTREGUE (GPS Validado a 25.0m)
Estado Final Consolidado: ENTREGUE
=================================================================
🌐 Exemplo de Payload JSON para Transição de Estado (Swagger /docs)
{
"codigo_rastreio": "BR-4401",
"transicao_solicitada": "CONFIRMAR_ENTREGA",
"dados_guarda": {
"latitude_atual": -23.55052,
"longitude_atual": -46.63331,
"distancia_calculada_metros": 25.0
}
}
📤 Instruções de Entrega (Microsoft Teams)
Após validar suas documentações técnicas de estados:
- Salve o arquivo de tabela com o nome
Atividade_12.mde a imagem do seu diagrama com o nomeAtividade_12.pngna pastaes-atv-12-estados/do seu repositório GitHub. - Certifique-se de fazer o commit e push para o repositório público.
- Submeta o link do seu repositório no Microsoft Teams para avaliação do professor.
💡 Checkpoint de Lógica
Reflexão Profissional: O que diferencia, na modelagem profissional, um Estado de uma Atividade? (Resposta: Um Estado representa uma situação de estabilidade temporária onde o objeto está aguardando passivamente um evento externo para mudar. Uma Atividade é uma ação ativa, de execução procedural contínua e computacional direta, que transiciona automaticamente para o próximo passo assim que termina). 🧠🛡️
📊 Rubrica Formativa de Avaliação
| Critério de Avaliação | Insuficiente (0% - 40%) | Regular (41% - 70%) | Excelente (71% - 100%) |
|---|---|---|---|
| Máquina de Estados & Condições de Guarda | Menos de 4 estados ou transições sem eventos gatilho claros. | Mapeia os 4 estados mas sem declarar as condições de guarda `[...]`. | Diagrama de máquina de estados impecável com ao menos 4 estados, eventos gatilho e guardas `[...]` de proteção. |
| Tabela de Transições Lógicas | Omite a tabela de transições lógicas. | Preenche a tabela com colunas incompletas. | Tabela detalhada de transições de estado cobrindo Estado Origem, Gatilho, Guarda e Estado Destino. |
| Entrega no GitHub | Entrega fora da pasta `es-atv-12-estados/`. | Entrega apenas o arquivo markdown sem a imagem `.png`. | Submete `Atividade_12.md` e `Atividade_12.png` no repositório com validação de padrão. |