domingo, 31 de agosto de 2014

BeanMaker, Gerador de Código - Arquitetura

Aprendi com o professor Carlos Ribeiro o desenvolvimento em camadas em Java. Ele nos mostrou como implementar um DAO Genérico usando JPA e JDBC. Trago essas lições até hoje.

Fiz uma pequena modificação no modelo ensinado com maestria por ele, inserindo a camada "Transaction". Ela tem por objetivo maximizar o reuso dos serviços existentes.

Um serviço é uma peça de código que executa uma regra de negócio dentro de uma transação de Banco de Dados. Uma transação de Banco de Dados garante que: (a) Ou toda a regra de negócio é executada (b) Ou nenhuma parte da regra de negócio é executada. Por exemplo: Imagine uma transação do setor bancário por ser muito bem conhecida de todos nós: o Saque. Ela é composta por duas ações básicas: (1) Retirada do Valor da Conta e (2) Gravação do Lançamento no Extrato. Teria mais ou menos a seguinte ordem:
  (Serviço de Saque)
  1) Início da transação do Banco de Dados
  2) Tratamento do débito
  3) Gravação do Extrato
  4) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  5) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)

Da mesma forma, uma transação de Depósito teria a seguinte estrutura:
  (Serviço de Depósito)
  1) Início da transação do Banco de Dados
  2) Tratamento do crédito
  3) Gravação do Extrato
  4) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  5) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)

Essas transações na vida real são mais complexas do que isso. Um Saque somente pode ser realizado se houver saldo em conta, por exemplo.

Trabalhando com a arquitetura sem a nova camada "Transaction", senti dificuldades para construir "serviços" a partir de outros "serviços", uma vez que ele já englobava o controle de transações do Banco de Dados. Imagine que eu queira fazer uma regra de negócio para a "Transferência entre Constas", que é composta de "Saque na conta de origem" e "Depósito na conta de destino". Gostaria de ter um novo trecho de código que tivesse a seguinte estrutura:
  (Serviço de Transferência Entre Contas)
  1) Início da transação do Banco de Dados
  2) Executar Serviço de Saque
  3) Executar Serviço de Depósito
  4) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  5) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)

Observe que, como tanto o Serviço de Saque como o Serviço de Depósito já possuem o controle de transação, não conseguiria que se ocorresse algum erro na transação de "Depósito" a transação de saque fosse desfeita.

Na verdade, quando chamamos uma transação dentro de uma outra transação é esperado que haja um erro de programação.

Para resolver esse problema é que a camada "Transaction" foi criada. Ela sempre conterá um trecho de código muito simples, como o modelo abaixo:
  (Transação Hipotética)
  1) Início da transação do Banco de Dados
  2) Executar Serviço Hipotético
  3) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  4) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)

Trazendo as regras de negócio para a nossa arquitetura com mais uma camada, teremos:
  (Serviço de Saque)
  1) Tratamento do débito
  2) Gravação do Extrato
  (Serviço de Depósito)
  1) Tratamento do crédito
  2) Gravação do Extrato
  (Serviço de Transferência Entre Contas)
  1) Executar Serviço de Saque
  2) Executar Serviço de Depósito

O que nos obrigaria ter as seguintes Transações:
  (Transação de Saque)
  1) Início da transação do Banco de Dados
  2) Executar Serviço de Saque
  3) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  4) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)
  (Transação de Depósito)
  1) Início da transação do Banco de Dados
  2) Executar Serviço de Depósito
  3) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  4) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)
  (Transação de Transferência Entre Contas)
  1) Início da transação do Banco de Dados
  2) Executar Serviço de Transferência Entre Contas
  3) Fim da Transação bem sucedida, com efetivação no Banco de Dados (commit)
  4) Fim da Transação mal sucedida, desfazendo as alterações no Banco de Dados (rollback)

Assentados esses conceitos, podemos prosseguir na demonstração do BeanMaker.

Nenhum comentário:

Postar um comentário