Pular para o conteúdo

apps/data-patterns/data-access-styles

097 · Dados & Persistência · ≈ 6 min de estudo

Data Access Styles: Active Record vs. Data Mapper

Duas formas clássicas (Fowler, Patterns of Enterprise Application Architecture) de ligar o objeto de domínio ao banco. No Active Record o próprio objeto se carrega e se salva; no Data Mapper um objeto separado traduz entre o domínio puro e a linha da tabela. Use Active Record em CRUD simples e Data Mapper onde há regra de negócio a testar sem banco.

passos
6
arquivos
9
testes
2
tecnologias
5
Infraestrutura realTypeScriptBunElysiaPostgreSQLDocker
Baixar cartão

Cenário

Banco digital com dois agregados de naturezas diferentes. O favorecido PIX (apelido, chave, banco) é cadastro puro, sem regra — cabe no Active Record. A conta corrente tem regra: saque não passa do saldo, conta encerrada não movimenta e só encerra com saldo zero — pede Data Mapper, com a regra testável sem banco.

Planta

Fluxo
5/5
Active Record - favorecidos PIXData Mapper - contasAPI do banco - ElysiaJSBeneficiary.create / findbeneficiary.save() / destroy()MapperAccountidFind / insert / updateAccountdeposit / withdraw / closesem import de bancobeneficiariesaccountsreconstrói elê o snapshot
5

5 passos — reproduza para seguir o fluxo

Como funciona

6 passos

Objeto que se salva ou mapeador dedicado.

Esconde cada passo: lembre antes de tocar para revelar.

  1. 01

    Beneficiary recebe o pool uma vez (connectionEstablish) e expõe create, find, save e destroy: modelo e gateway da tabela são a mesma classe

  2. 02

    Alteração num favorecido fica em memória até beneficiary.save()

  3. 03

    Account só tem regras (deposit, withdraw, close) e não importa nada de banco; nasce sem id

  4. 04

    MapperAccount recebe o pool ou o client da transação por injeção: insert dá a identidade, idFind reconstrói o objeto, update grava o snapshot

  5. 05

    Cada movimentação carrega a conta com FOR UPDATE, aplica a regra e grava na mesma transação

  6. 06

    Um estilo por agregadoNenhuma entidade mistura os dois

Trade-offs

O que se ganha, o que se paga

Aspecto Active Record Data Mapper
Código inicial Menor: uma classe Maior: domínio e mapper
Acoplamento Classe conhece a tabela e o pool Domínio ignora o banco
Teste da regra Exige banco Unitário puro
Domínio rico Classe incha com regra e SQL Regra cresce sem carregar SQL

apps/data-patterns/data-access-styles

9 arquivos

sql/

  • 01_schema.sqlschemaTabelas beneficiaries e accounts

src/

  • beneficiary_active_record.tsActive Record: Beneficiary com SQL próprio
  • account.tsDomínio puro da conta, sem banco
  • mapper_account.tsData Mapper: MapperAccount traduz linha e objeto
  • api_bank.tsRotas /beneficiaries e /accounts
  • demo.tsdemoFluxo dos dois estilos pela API
  • account.test.tstesteRegras da conta sem banco — o ganho do Data Mapper
  • api_bank.test.tstestePersistência dos dois estilos e concorrência contra PostgreSQL real

src/config_bank.ts / src/

  • pool_bank.tsAmbiente validado, pool e transactionExecute

Executar · com Docker

  1. ./docker.sh up# sobe PostgreSQL
  2. bun install# dependências
  3. bun run demo# roda o cenário
  4. 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 Data Access Styles?

Próximo projeto · Dados & PersistênciaScheduler Agent Supervisor
Esc

↑ ↓ navegarEnter abrir191 resultados