Olá a todos !
Aqui estou novamente com mais uma dúvida de modelagem X)
Tenho uma classe de Serviço que chama seu repositório para persistir a entidade. Até aí tranquilo. Porém, eu preciso persistir objetos diferentes na mesma ação e fiquei a me perguntar: o Repositório da entidade “principal” (se é que posso falar assim), pode chamar outros Repositórios passando a eles as informações de que eles necessitam para persistirem também ou seria mais interessante eu fazer essas rotinas na classe de Serviço ?
Eu explico o por quê disto: tenho objetos alinhados, ou seja: objetoA.objetoB.propriedade_objetoB o famoso “objeto dentro de objeto”. Assim como um objeto Pedido pode trazer um ArrayList de Produtos dentro dele.
A principio eu pensei: ah, repositório fala com repo tranquilamente, porém, essa pattern eu não domino muito ainda, vai saber que não é interessante isto (…)
Se os objetos estiverem todos relacionados com essa entidade principa, a sua ferramenta de persistência deveria ser capaz de persistir todos em cascata. o repositório principal não deveria se preocupar em persistir objetos relacionados não.
Meu caso é o seguinte: tenho uma entidade Reagendamento a qual contém dados sobre os reagendamentos efetuados na agenda (domínio: agenda) e em contra partida, eu tenho uma entidade Agendamento que cuida efetivamente dos agendamentos que aparecem na agenda.
Um reagendamento é nada mais do que: uma atividade estava agendada (entidade Agendamento) todas quartas-feiras até uma data X, porém, a partir da data Y ela será todas as quintas, por exemplo.
Como o sistema precisa manter o “passado” dessa agenda intacto em caso de atualizações, eu preciso finalizar o primeiro Agendamento, criar o novo (na quinta à partir da data Y) e a entidade Reagendamento controla as duas entidades Agendamento (a antiga e a nova) além da data Y e quem alterou isto.
Modelei a Reagendamento da seguinte forma:
Reagendamento.agendamento_antigo - que contém o Agendamento antigo
Reagendamento.agendamento_novo - que contém o objeto Agendamento novo
Reagendamento.autor - que contém o objeto Usuario
Reagendamento.data - que contém a data de inicio desse reagendamento
Então, numa ação de reagendamento, a Entidade Reagendamento precisa persistir as informações delas (pois isso será usado depois para relatórios)
e também, cancelar o Agendamento antigo e criar o novo Agendamento
As ações de criar e cancelar os Agendamentos, a própria Service do Agendamento está cuidando tranquilamente. Eu preciso apenas chamá-las para que façam suas partes. (Cancelar e Criar o novo)
E não, não estou usando nada parecido com hibernate. A grosso modo seria um JDBC comum com DAO e etc =/
Vc tera que fazer o trabalho que seria feito pela ferramenta ORM, mas como essa responsabilidade é da camada de infraestrutura a principio pouco importa se repositorios vao chamar outro diretamente ou nao. Particularmente acho que isso pode te levar a criar repositorios de forma indiscriminada.
Implementacao do repositorio tb e infraestrutura portanto nada impede que o carregamento das associacoes seja feito usando jdbc puro, sem que o dominio fique poluido. Tb nem todas entidades possuem repositorios.
Sim, eu poderia implementar diretamente na DAO, mas eu estava pensando no seguinte: a manutenção. Se eu colocar diretamente na DAO, eu teria código duplicado, pois os comportamentos de adicionar novo agendamento e finalizar um agendamento existem já no serviço Agendamento.
Pensando mais a fundo desta forma (na manutenção), penso que deixar o Serviço Reagendamento delegar a Finalização e Criação dos agendamentos seria uma saída interessante, pois qualquer alteração no meu Agendamento, eu teria apenas um lugar para alterar, e não dois (no caso dos sqls da DAO).
O ideal é que o seu repositório faça isso (verifique as entidades relacionadas e salve elas de acordo), pois pode vir a acontecer de um reagendamento ser criado fora desse serviço.
Aparentemente, no seu caso, a única coisa que já não está gravada é o “agendamentoNovo”, então seria simples fazer o seu repositório de Reagendamentos delegar para o repositório de Agendamentos a gravação do tal “agendamentoNovo”.
Uma outra idéia colocaria um método-fábrica no repositório de Agendamentos que crie um Reagendamento, já que ele não é uma coisa que existe sozinha, ele depende da existência do Agendamento antigo. Esse método poderia receber os dados e já criar o reagendamento (salvando o reagendamento e o novo agendamento) no banco de dados diretamente.
Assim você não cria um outro repositório só pra criar Reagendamentos, mas isso pode ser um problema se dentro do seu sistema você busca diretamente por Reagendamentos.
Sim, eu poderia implementar diretamente na DAO, mas eu estava pensando no seguinte: a manutenção. Se eu colocar diretamente na DAO, eu teria código duplicado, pois os comportamentos de adicionar novo agendamento e finalizar um agendamento existem já no serviço Agendamento.
Pensando mais a fundo desta forma (na manutenção), penso que deixar o Serviço Reagendamento delegar a Finalização e Criação dos agendamentos seria uma saída interessante, pois qualquer alteração no meu Agendamento, eu teria apenas um lugar para alterar, e não dois (no caso dos sqls da DAO).
O que acha ?
s4nchez, vou pesquisar sim. Agradeço a dica !
Abraços!
[/quote]
Voce parece ter bons argumentos que justificam sua decisao mas ela visa aprimorar um infraestrutura de persistencia que poderia ser preenchida por uma ferramenta de mercado. Se vc vai ter que fazer esse trabalho eu presumo que menor atencao sera dedicada aquilo que gera valor pro cliente.
O ideal é que o seu repositório faça isso (verifique as entidades relacionadas e salve elas de acordo), pois pode vir a acontecer de um reagendamento ser criado fora desse serviço.
Aparentemente, no seu caso, a única coisa que já não está gravada é o “agendamentoNovo”, então seria simples fazer o seu repositório de Reagendamentos delegar para o repositório de Agendamentos a gravação do tal “agendamentoNovo”.
Uma outra idéia colocaria um método-fábrica no repositório de Agendamentos que crie um Reagendamento, já que ele não é uma coisa que existe sozinha, ele depende da existência do Agendamento antigo. Esse método poderia receber os dados e já criar o reagendamento (salvando o reagendamento e o novo agendamento) no banco de dados diretamente.
Assim você não cria um outro repositório só pra criar Reagendamentos, mas isso pode ser um problema se dentro do seu sistema você busca diretamente por Reagendamentos.[/quote]
Essa discussoa nao tem nada a ver com DDD ou repositorios, mas com infraestrutura de persistencia. Quando nao tinhamos ferramentas do tipo hibernate DDD era inviavel, isso continua valendo hj pra quem precisa transitar entre o mundo relacional e de objetos.
Bem, não entendi o que você quis dizer, mas DDD sempre foi possível, seja com ou sem Hibernate ou ferramentas de ORM, não vejo nada de impossível em implementar um modelo seguindo o DDD e usando repositórios sem usar Hibernate, só vai ser, obviamente, mais complicado.
Bem, não entendi o que você quis dizer, mas DDD sempre foi possível, seja com ou sem Hibernate ou ferramentas de ORM, não vejo nada de impossível em implementar um modelo seguindo o DDD e usando repositórios sem usar Hibernate, só vai ser, obviamente, mais complicado.[/quote]
Eu to falando de object-relational impedance mismatch. Era inviavel porque era tao complicado ao ponto de justificar a utilizacao de banco de dados OO, nao disse que DDD era impossivel.
Pois é ! Estou sentindo na pele isto. Como não tem como fugir, a solução é encontrar a saída mais “viável” para este “problema” de falta de ORM na aplicação X)
[quote=“Mauricio”]O ideal é que o seu repositório faça isso (verifique as entidades relacionadas e salve elas de acordo), pois pode vir a acontecer de um reagendamento ser criado fora desse serviço.
Aparentemente, no seu caso, a única coisa que já não está gravada é o “agendamentoNovo”, então seria simples fazer o seu repositório de Reagendamentos delegar para o repositório de Agendamentos a gravação do tal “agendamentoNovo”. [/quote]
A princípio todo reagendamento utilizará o mesmo serviço. Talvez no futuro mude, mas o escopo atual não precisa disto.
Como o cmoscoso citou estou “me matando” com isto pois não tenho uma ferramenta ORM cuidado da persistência, logo, ao que entendi eu poderia sim fazer uma delegação para outro Repositório.
Você citou o possível uso de uma factory method, mas como você mesmo disse, eu precisarei buscar os reagendamentos feitos para gerar relatórios depois, por isso preciso deles separados. Entretanto, poderia eu usar uma façade no RepositórioAgendamento para realizar o Reagendamento (finalizar um agendamento e criar outro), ou será que seria desperdício de tempo ? X)
Não é uma boa idéia fazer o repositório depender de uma fachada do sistema, pior, vai terminar criando um ciclo, repositório depende de fachada que depende de repositório.
Não é uma boa idéia fazer o repositório depender de uma fachada do sistema, pior, vai terminar criando um ciclo, repositório depende de fachada que depende de repositório.[/quote]
huum ! verdade. Só complica, não acaba ajudando muito.
s4nchez,
Eu li sobre o que me sugeriu. Pelo que entendi é recomendado termos um repositório só, mas acho que para rolar isso bem precisaria ter um ORM para fazer a infra de persistência, como nesse meu caso não tenho, ficaria difícil manter um repo apenas. Daí neste caso, teria - acho - que manter um repositório per entity. Foi isso que pude entender da pesquisa que fiz