Repositorio otimizado, account

A seguinte situação:
Um simples relatório que mostra as contas a receber de um período x,y.

repoCR.contasRecPeriodo(x,y) => tras obj de ContaRec, baseado no padrão account(padrão account não é relevante nesse contexto)

No repoCR.contasRecPeriodo(x,y), ocorre o seguinte: (exemplo simplificado)
1 monta QueryObject
2 passa para o DomainStore (hibernate no caso)

ate aqui tranqüilo, a questão seria a seguinte: (exemplo simplificado)
o ContaRec tem ContaRec.Saldo, Saldo retorna a diferença entre lançamentos de D e C (como eu disse exemplo simplificado). Quando faço a apresentaçao dos obj contaRec a cada iteração faço um acesso a .saldo, logo no método saldo tenho:

  1. RepoCR.entryAll => retorna list de obj entry para calculo do saldo da conta.
  2. Faço um loop para compor o saldo = D e Entry = C a diferença entre D C = meu saldo.

Pergunta: vemos q a cada iteração tenho uma consulta, .salo . De fato isso se torna lento para a apresentação. Tudo bem que isso seria um custo do SoC, porem o repoCR.contasRecPeriodo não poderia ser mais inteligente e fazer ou tentar decompor o saldo ao trazer os obj contaRec.
Logo vejo as seguintes situações:

1 repoCR.contasRecPeriodo não cria QueryObject, visto ser limitado(no meu caso) para determinadas otimizações, e faz uma acesso direto a base de dados eliminando o papel do domainstore. Faz um SELECT direto. Porem fica a duvida de como o repositório ira traduzir o retorno do jdbc para o obj, sem o papel do Domainstore

2 no método contaRec.saldo, realmente esta certo o papel do repositório trazendo os lançamentos e depois os decompondo. Pergunto isso pq no padrão account isso fica implícito.

3 caso a possibilidade 1, seja aceita, não seria mais interessante, agora sim nesse caso, generalizar DomainStore, ou o DAO do DomainStore? Visto que, se uso o hibernate para ter flexibilidade de bancos de dados, no caso em que exista a possibilidade de otimização(e existe mto visto, os relatorios) em muitos casos não usaria o hibernate, e sim um acesso diferenciado que tb poderia ser flexível para qualquer SGDB. Vejam aqui q somente existe a necessidade de uso de SGDB.

Vc não está seguindo o padrão Account à risca.
Se estivesse seria o account a ter o método contasrecPeriodo

Um account é um conjunto de movimentos (lançamentos) os movimentos alteram o saldo que é zero quando não ha movimentos.

O account tem portanto um addMovimento() na sua interface. é guardando o account no repo que os movimentos são guardados em cascada. No addMovimento o saldo é atualizado em uma variável interna. logo o getSaldo() não faz calculo algum.


public void addMovimento ( Movimento  movimento ){

    this.saldo += movimento.getRelativeValue();  // negativo para debito e positivo para credito
this.movimentos.add(movimento);
}

O carregamento dos movimentos é que é a parte chata. Se o repositorio de account fizer esse trabalho, usar o addmovimento é suficiente. Se tiver alguma magica do hibernate não tem jeito , vc tem que iterar a coleção de movimentos à postetiori. vc pode fazer apenas com lazyloading do saldo ele mesmo


Money saldo; // é objeto e é nulo

public void saldo(){

    if ( saldo == null ){
     // soma tudo  e faz cache 
            saldo = new Money();
           for (Movimento mov : movimentos){
                   saldo =  saldo.add(mov.getRelativeValue();
           }
   }
   return saldo; 
} 

A rapidez da soma depende do numero de movimentos a somar, mas só se faz uma vez

Se isso não ajudou vamos às suas perguntas

sim a responsabilidade recai no repositorio de traduzir o jdbc para objetos

É assim que tem que ser. Mas é claro que o account pode chamar os repositorios por detrás dos panos quando entender de deve.
( por exemplo, não faz sentido carregar todos os ovimentos no account se eles nunca serão usado , por exemplo o cara só quer o numero da conta )

Sim, voce pode generalizar o seu domainstore, mesmo que esteja usando o Hibernate. é uma questão de desacoplamento.
Em opção vc pode simplesmente reescrever o repositorio. Isso e´geralmente ruim. O meio termo é ter uma camada entre o repsoitorio e o domainstore final se ele não é flexivel. Vc pode ter a sua propria interface de domainstore e duas implementações, uma com hibernate e uma com JDBC directo. o primeiro é melhor para edição e o segundo para leitura. ( … vai dai, com um Domainsotre em JBDC vc nem precisa do Hiberbanete, mas aviso já que criar um DomainStore independente do banco não é tão rápido e simples assim. Para inspiração dê uma olhada no sistema de domainstore do MiddleHeaven

sim existe falhas na implementaçao, eu nao gostaria mas existem.
1 Porem, desculpe, fiquei so com duvida, entao nao existe um repo que carrega meus obj account. Ou vc quis dizer q existe um metodo em account contasrecPeriodo q tras os lançamentos do mesmo.

2 essa variavel interna saldo pode ser persistida? se sim entao quando faço um load dos obj account, estaria ja carregando o saldo calculado tb? ou melhor, quando persisto account e logo seus lançamentos em cadasta, tb posso persistir o saldo ja calculado assim ganho uma boa perfomace.
Poderia usar os lançamentos para recalcular os saldos em caso de alguma inconsistencia.

sim, generalizar um DomainStore esta longe de minhas intençoes visto o alto grau de complexidade. entao a saida mais facil realmente em casos de otimizaçoes de relatorios é fazer direto via jdbc dentro do repo. se tenho flexibilidade de sgbds entao tenho q fazer dentro do repo mesmo uma consulta para cada banco, coisa simples sem padrao mesmo. Porem isso demostra quanto o repo é importante, se ninguem olhar para dentro do repo o dominio continua com um bom jeiro. quanto ao Middlehaeven estou olhando valeu
Obrigado pela atençao