Probleminha OOAD (DDD Repositórios)

Desculpe pela minha prática de necromancia neste tópico, mas o Philip Calçado postou sobre o uso que estão fazendo num projeto de integração entre sistemas com a idéia do Yoshima de Repositórios do DDD.

http://fragmental.tw/2010/02/24/everyday-tales-anatomy-of-a-refactoring/ (em inglês)

Só quero ver a continuação dessa refatoração deles.

[quote=Bruno Laturner]Desculpe pela minha prática de necromancia neste tópico, mas o Philip Calçado postou sobre o uso que estão fazendo num projeto de integração entre sistemas com a idéia do Yoshima de Repositórios do DDD.

http://fragmental.tw/2010/02/24/everyday-tales-anatomy-of-a-refactoring/ (em inglês)

Só quero ver a continuação dessa refatoração deles.[/quote]

two wrongs don’t make a right.

O problema não é semantico, como as pessoas parecem acreditar.
E a sugestão seguida foi apenas a nomenclatura e não o modelo.
O modelo do TodosX era de uma registro abstrato, não de uma interface.
Extrair a interface para TodosX mas continuar usando XRepository como implementação não mudou uma virgula no modelo.
É algo apenas estético, porque força uma separação (articial) entre o que é considerado “dominio” e o que é considerado “estrutura”.

O repositorio é parte do dominio e não ha vergonha nenhuma nisso. Chame-se como se chamar , com prefixo ou sem. Ele contém regras do dominio
regras que fazem ganhar e perder dinheiro, não apenas coisas de canalização de API (plumbing).
É isto que as pessoas ainda não entenderam.

Coisas como o modelo do repositorio implementa um interface é coisa de DAO. E é realmente isso que o modelo aponto. Uma interface que é implementa na infra , mas usada como um serviço. Ou seja, amanhã é possivel eu implementar outra forma e substituir , ou até ter um façade que escreve nos dois reposiotrios (velho e novo) ao mesmo tempo. Isto é legal no DAO mas é absurdo no Repositorio. Se o repositorio muda, isso significa que o negocio mudou. As regras mudaram. O dominio foi alterado. Não a infra.

O modelo do repositorio inventado pelo proprio Fowler é muito mais coreente que isso e se as pessoas deixassem de pensar em interfaces seria muito mais simples. Definir repositorio como interfaces é como definir cliente e produto como interfaces. É programaticamente válido, mas um erro de abstração.

Repositorios sempre são acompanhados de estratégias. São dois objetos diferentes não uma interface e uma implementação (isso é um Service).
O repositorio contem e concentra as regras de negocio, especialmente que são relevantes a procuras. não contem codigo de infra.
A estratégia só contém codigo de infra e nada de negocio. Ela intrpereta a intenção do repositorio para a tecnologia real.

Um UserRepository tem (não “é”, composição, não herança) estratégias de pesquisa. Em particular ele contém várias. Uma estratégia por rede social. È como se, num sistema de banco de dados o repositorio comunicasse com vários bancos . ele teria uma estratégia por banco.

[quote=osmio][code]

Reserva reserva = new Reserva();
reserva.setDataInicioPeriodo(xxx);
reserva.setDataTerminoPeriodo(yyy);
reserva.setTipoAcomodacao(“Quarto de luxo”);

List<Quarto> quartosDisponiveis = QuartoRepository.getQuartosDisponiveis(reserva);
for (Quarto q : quartosDisponiveis) {
// lista os quartos disponíveis da melhor maneira
}

[/code]

Não é o caso do repositório saber quais quartos devem ser disponibilizados de acordo com a reserva?

[/quote]

Isso é o uso de Template Object para fazer a pesquisa.
Vc poderia escrever o mesmo assim

[quote=osmio][code]

List&lt;Quarto&gt; quartosDisponiveis = QuartoRepository.getQuartosDisponiveis(datainicio, dataFim, tipoAcomodacao);

Ou, o que é equivalente

List&lt;Quarto&gt; quartosDisponiveis = QuartoRepository.getQuartosDisponiveis(periodo, tipoAcomodacao);

Isto desacopla a Reserva. Mas veja que cada Quarto tem N reservas, mas cada reserva apenas um quarto.
Então nesse seu modelo, eu tenho um conjunto de quartos, mas ainda terei que escolher 1 e depois criar a reserva.

Poderiamos pensar que a sua pesquisa é equivalente a

List&lt;Reserva&gt; reservasDisponiveis = ReservaRepository.getReservaDisponiveis(periodo, tipoAcomodacao);

Que o Rodrigo já descartou porque “Reserva disponivel” não é um conceito do dominio. Nessa mesma logica “Quarto disponivel” também não é, e portanto nenhuma das duas pesquisas pode ser feita. :slight_smile:

[quote=osmio][quote=sergiotaborda]
Isto desacopla a Reserva. Mas veja que cada Quarto tem N reservas, mas cada reserva apenas um quarto.
Então nesse seu modelo, eu tenho um conjunto de quartos, mas ainda terei que escolher 1 e depois criar a reserva.
[/quote]

E não é este o requisito?
Olhe o primeiro post:

[/quote]

não atende porque vc não efetuou a reserva.

[quote=osmio][quote=sergiotaborda]
não atende porque vc não efetuou a reserva.
[/quote]

Então, nesse caso, não é necessário um quarto para fazer uma reserva?

Mas de qualquer forma, a reserva foi feita. Veja novamente:
[/quote]

não foi feita,exactamente, porque, vc não associou um quarto à reserva
Além disso essa reserva que vc cria é apenas um template ela não existe ainda.


Reserva reserva = new Reserva();
reserva.setDataInicioPeriodo(xxx);
reserva.setDataTerminoPeriodo(yyy);
reserva.setTipoAcomodacao("Quarto de luxo");

List&lt;Quarto&gt; quartosDisponiveis = QuartoRepository.getQuartosDisponiveis(reserva);
for (Quarto q : quartosDisponiveis) {
  // lista os quartos disponíveis da melhor maneira
}

Não é o caso do repositório saber quais quartos devem ser disponibilizados de acordo com a reserva?

E não é este o requisito?
Olhe o primeiro post:

Reserva controlar, também esta fora de questão para mim.

Então, nesse caso, não é necessário um quarto para fazer uma reserva?

Mas de qualquer forma, a reserva foi feita. Veja novamente:

Reserva reserva = new Reserva();  
reserva.setDataInicioPeriodo(xxx);      // Estou efetuando uma reserva com data de inicio
reserva.setDataTerminoPeriodo(yyy);  // e data de término
reserva.setTipoAcomodacao("Quarto de luxo"); 

// persistir a reserva antes de achar um quarto, torna a reserva efetivada? Então, persista a reserva aqui.

List&lt;Quarto&gt; quartosDisponiveis = QuartoRepository.getQuartosDisponiveis(reserva);  
for (Quarto q : quartosDisponiveis) {  
  // lista os quartos disponíveis da melhor maneira  
  if (q.getDescricao().equals("Quarto dos sonhos") {
    reserva.addQuarto(q);
  }
} 

// aqui, é necessário atualizar o modelo da reserva novamente para adicionar o(s) quarto(s).

Então eu tenho que associar um quarto a reserva, depois listar os quartos disponiveis?
Aparentemente, estamos entendendo de forma diferente o requisito.

O objetivo de listar os quartos é justamente selecionar qual o quarto que será associado a reserva. E não efetuar a reserva com um quarto e depois listar os quartos disponíveis.