Pular para o conteúdo

apps/service-design/state-pattern

171 · Padrões de Design de Serviço · ≈ 5 min de estudo

State

Cada status de uma transação vira uma classe com a mesma interface, e cada classe decide sozinha quais ações aceita a partir dela. Não existe switch (status): quem orquestra chama transactionStateFor(atual).cancel() e recebe o próximo status ou um erro dizendo por que não. Use quando o comportamento depende do status e as regras de transição crescem com o ciclo de vida.

passos
5
arquivos
4
testes
0
tecnologias
5
Infraestrutura realTypeScriptBunElysiaPostgreSQLDocker
Baixar cartão

Cenário

Um PIX nasce pending, vai para a câmara (processing) e termina settled; o cliente pode cancelar enquanto ainda está pendente. Depois que a câmara recebeu, cancelar não é mais possível — estorno é uma transação nova. O backoffice e o cliente agem sobre a mesma transação ao mesmo tempo, e uma decisão tomada sobre uma leitura antiga não pode sobrescrever o status mais novo.

Planta

Estados
6/6
pendingprocessingcancelledsettledcancel recusado: a camara ja recebeu,estorno e outra transacaoabrirprocesscancelsettle
6

6 passos — reproduza para seguir o fluxo

  • chamada
  • resposta ou assíncrono
  • falha
  • passo
  • toque num nó para focar
  • repouso ou sucesso
  • transição
  • falha ou recusa
  • Outras plantas de estados

Como funciona

5 passos

Comportamento muda com o estado.

Esconde cada passo: lembre antes de tocar para revelar.

  1. 01

    StateTransactionPending, StateTransactionProcessing, StateTransactionSettled e StateTransactionCancelled implementam process, cancel e settle; ação inválida lança ErrorTransitionInvalid com status, ação e motivo

  2. 02

    TRANSACTION_STATES é a única lista dos estados e acompanha o CHECK da coluna status

  3. 03

    A API carrega a transação e pergunta ao objeto de estado; recusa vira 409 com a mensagem do estado

  4. 04

    O UPDATE ... WHERE status = $atual aplica a decisão e grava a transição em transaction_transitions no mesmo comando

  5. 05

    Zero linhas atualizadas significa que o status mudou depois da leitura: ErrorTransitionConcurrent, nunca sobrescrita

Trade-offs

O que se ganha, o que se paga

4 vantagenscada ganho tem um preço4 custos

Vantagens

  • Nenhum switch de status espalhado

  • Estado novo não altera os existentes

  • Transição inválida explícita, com motivo

  • Guarda otimista impede sobrescrever status mais novo

Custos

  • Uma classe por estado, mesmo os finais

  • Mapa de estados e CHECK do banco precisam andar juntos

  • Para dois estados, três if bastam

  • Quem perde a corrida precisa reler e decidir de novo

apps/service-design/state-pattern

4 arquivos

src/

  • state_transaction.tsInterface, as quatro classes de estado e o mapa TRANSACTION_STATES
  • repository_transaction.tsTransição com guarda otimista e registro no histórico
  • api_transaction.tsUma rota por ação, sem switch de status

sql/

  • 01_schema.sqlschemaTransações com CHECK de status e histórico de transições

Executar · com Docker

  1. ./docker.sh up# sobe PostgreSQL
  2. cp .env.example .env# variáveis de ambiente
  3. bun install# dependências
  4. bun run demo# roda o cenário
  5. bun run test# integração contra o serviço real
Requisitos
BunDocker
Sobe junto
PostgreSQL

Por que se relacionam

Teste rápido

Qual destes combina com State Pattern?

Próximo projeto · Padrões de Design de ServiçoTemplate Method
Esc

↑ ↓ navegarEnter abrir191 resultados