Probleminha OOAD (DDD Repositórios)

[quote=fantomas]rodrigoy

Entendi o seu ponto de vista e tenho pensado bastante sobre o assunto (mas ainda não o suficiente); o que me incomoda um pouco nesta estratégia de criar o nome da classe que vc adotou é que o nome de uma classe segundo as “regras” da OO não deveria ser no plural e sim no singular. Corrija-me se achar que estou enganado.
[/quote]

Te corrijindo, você está enganado:

Este não é o original da ISO. Pelo que me lembro isso entrou no padrão por conta da Literatura do Rumbaught de 1991.

TodasReservas representam uma coleção de Reservas.

:wink:

rodrigoy

Obrigado pela correção!

Mas o meu incomodo com isto é em relação ao significado das coisas: por exemplo, seria muito mais simples a sugestão de nomes como People para todas pessoas ou WholeCars para todos os carros ao invés de PersonRepository ou CarRepository (me incomoda também a palavra repository). O que acontece é que quando se diz PersonRepository transmite a idéia, ao menos para mim, de que estou lidando com UM mecanismo agregador (repository) de entidades originadas DA (única) classe Person.

Valeu pela dica, vou pensar mais sobre o assunto.

Ótimo topico.

flws

O gomesrod levantou um ponto interessante.
Se existisse o método obterQuartosReservados não faria sentido colocá-lo em TodosQuartos pois a Reserva já possui um Quarto.
Apesar de, na minha opinião ficar bem semântico, também não faria sentido colocar o método obterQuartosReservados em TodasReservas e o método obterQuartosDisponíveis em TodosQuartos.
Logo, ainda vejo como melhor opção colocá-lo no repositório de reservas!

[quote=fantomas]por exemplo, seria muito mais simples a sugestão de nomes como People para todas pessoas ou WholeCars para todos os carros ao invés de PersonRepository ou CarRepository
[/quote]

PersonRepository, PessoaRepository, PessoaRepositorio não faz sentido para as pessoas do domínio. Esse é o meu ponto. WholeCars não faz sentido. Estamos dando exemplos em português.

Rodrigo, não me leve a mal e o que vou dizer a seguir é apenas para ajudar.
Vc está exigindo escolher 1 de 3 pre-definidas. Eu não considero nenhuma delas a resposta certa. Não sei se isso é de propósito para estabelecer algum ponto no curso mas, eis como eu resolveria :

Vc tem que mostrar os quartos disponíveis, mas isso não significa que tenha que procurar os quartos disponíveis.
O que vc quer, na realidade é mostrar quais reversas são possíveis para que a pessoa escolha uma. O quarto, como mostrou, é um dos fatores, mas as datas são outro. Se o quarto está disponível apenas por 1 dia e a pessoa vai ficar três, então esse quarto não pode ser reservado e não deve aparecer como opção.

A minha resposta seria então :

d. Faço uma pesquisa em TodasReservas por getReservasPossiveis(Periodo)

Isso irá trazer uma lista de objectos reserva com as datas iguais às do periodo e os quartos iguais aos disponiveis. Se vc quiser mesmo mostrar os quartos vc usar reserva.getQuarto()

É claro que por detrás dos panos vc irá procura apenas os quartos e montar os objettos reserva “on demand” no repositorio porque essas reservas não existem “fisicamente” no banco. Mas existem no dominio. Tanto é que vc está procurando por elas.

[quote=luistiagos][quote=viniciusv]Só uma sugestão: que tal trocar TodosQuartos.getDisponiveis(periodo) por TodosQuartos.disponiveisEm(periodo) ?
Nomes são importantes. E se a língua escolhida para nomear as coisas for o português, provavelmete não existirá esse ‘get’ na linguagem do domínio.[/quote]

Por padrão na nomeclatura da propria sun e aconselhavel usar getters e setters… talvez vc pense que isto e uma tremanda de uma bobagem… [/quote]

A sun usa para javabeans e ejb que são tecnologias, não padrões. Outros frameworks usam beans (não javabeans) e get/set representam as propriedades do bean.
A ideia do viniciusv é válida porque disponíveis não é uma propriedade de TodosOsQuartos porque esse objeto não é um bean , nem um javabean , nem um (entity) EJB : ou seja, ele não tem propriedades logo ele não têm get/set .
O prefixo padrão para reposiorios é find e poderiamos colocar encontraDisponiveis. Mas disponiveisEm é ainda melhor. (curiosamente find era o prefixo em ejb 2 para métodos de pesquisa, que são na essencia o que constitui um respositorio)

[quote=luistiagos][quote=viniciusv][quote=luistiagos][quote=viniciusv]Só uma sugestão: que tal trocar TodosQuartos.getDisponiveis(periodo) por TodosQuartos.disponiveisEm(periodo) ?
Nomes são importantes. E se a língua escolhida para nomear as coisas for o português, provavelmete não existirá esse ‘get’ na linguagem do domínio.[/quote]

Por padrão na nomeclatura da propria sun e aconselhavel usar getters e setters… talvez vc pense que isto e uma tremanda de uma bobagem… porem se for usar reflection para automatizar um pouco as coisas precisara de td em um padrão… dai sim vc vai ver a verdadeira utilidade de padrão para nomeclaturas…[/quote]

Padrões, reflection ou qualquer outro aspecto meramente computacional não pode ser razão pra nomear as coisas na camade de domínio. Tratam-se de complexidade acidental [1], não coisas que, de fato, fazem parte do domínio em questão. Pense no mesmo sistema mas implementado usando Python ou Ruby.

[1] http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959[/quote]

Talvez… mas ja parou pra pensar pq a propria sun resolveu criar um padrão? padrões é algo maravilhoso na hora de vc desenvolver algo… se algo e padronizado e tem digamos uma classe com um atributo custa… se vc usa padrões para os nomes em qualquer lugar vc deduzira que para retornar a custa chamara getCusta e não retornarCusta, exibirCusta, pegarCusta ou algo do genero… isto tornara implicito pois utiliza o padrão de nomeclatura… vc não precisa consultar a classe para saber como retornar determinado atributo…
isto se torna muito mais facil… mesmo que na outra maneira seja mais intuitivo… ou seja a padronização não serve so para o reflection saber oq ele esta fazendo e sim tbm para o programador saber o que ele esta fazendo sem precisar consultar o metodo para isto…[/quote]

Discordo. Getters/Setters são, na maioria das vezes, algo negativo. Objetos possuem estado e comportamento relacionados. É responsabilidade de um objeto receber mensagens e decidir por sí mesmo se muda de estado ou não. Getters/setters expõe a implementação do estado para fora da classe, fazendo com que este estado possa mudar imprevisivelmente e criando dependencias indesejáveis. Estado e lógica relacionados devem estar juntos [1]!

Além disso, getters/setters baseiam-se em implementação, não em intenção. Digamos que voce queira um método para justificar um parágrafo. Voce poderia fazer isso com um setter:

… que na verdade quer dizer “estou setando o valor CENTERED no attributo justification”. Não seria melhor…

… que diz exatamente o que voce quer, que é centralizar o parágrafo?

Recomendo a leitura desse post do Philip Calçado sobre esse assunto. Bem esclarecedor.

[1] http://www.amazon.com/Implementation-Patterns-Addison-Wesley-Signature-Kent/dp/0321413091

[quote=viniciusv][quote=luistiagos][quote=viniciusv][quote=luistiagos][quote=viniciusv]Só uma sugestão: que tal trocar TodosQuartos.getDisponiveis(periodo) por TodosQuartos.disponiveisEm(periodo) ?
Nomes são importantes. E se a língua escolhida para nomear as coisas for o português, provavelmete não existirá esse ‘get’ na linguagem do domínio.[/quote]

Por padrão na nomeclatura da propria sun e aconselhavel usar getters e setters… talvez vc pense que isto e uma tremanda de uma bobagem… porem se for usar reflection para automatizar um pouco as coisas precisara de td em um padrão… dai sim vc vai ver a verdadeira utilidade de padrão para nomeclaturas…[/quote]

Padrões, reflection ou qualquer outro aspecto meramente computacional não pode ser razão pra nomear as coisas na camade de domínio. Tratam-se de complexidade acidental [1], não coisas que, de fato, fazem parte do domínio em questão. Pense no mesmo sistema mas implementado usando Python ou Ruby.

[1] http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959[/quote]

Talvez… mas ja parou pra pensar pq a propria sun resolveu criar um padrão? padrões é algo maravilhoso na hora de vc desenvolver algo… se algo e padronizado e tem digamos uma classe com um atributo custa… se vc usa padrões para os nomes em qualquer lugar vc deduzira que para retornar a custa chamara getCusta e não retornarCusta, exibirCusta, pegarCusta ou algo do genero… isto tornara implicito pois utiliza o padrão de nomeclatura… vc não precisa consultar a classe para saber como retornar determinado atributo…
isto se torna muito mais facil… mesmo que na outra maneira seja mais intuitivo… ou seja a padronização não serve so para o reflection saber oq ele esta fazendo e sim tbm para o programador saber o que ele esta fazendo sem precisar consultar o metodo para isto…[/quote]

Discordo. Getters/Setters são, na maioria das vezes, algo negativo. Objetos possuem estado e comportamento relacionados. É responsabilidade de um objeto receber mensagens e decidir por sí mesmo se muda de estado ou não. Getters/setters expõe a implementação do estado para fora da classe, fazendo com que este estado possa mudar imprevisivelmente e criando dependencias indesejáveis. Estado e lógica relacionados devem estar juntos [1]!

Além disso, getters/setters baseiam-se em implementação, não em intenção. Digamos que voce queira um método para justificar um parágrafo. Voce poderia fazer isso com um setter:

… que na verdade quer dizer “estou setando o valor CENTERED no attributo justification”. Não seria melhor…

… que diz exatamente o que voce quer, que é centralizar o parágrafo?

Recomendo a leitura desse post do Philip Calçado sobre esse assunto. Bem esclarecedor.

[1] http://www.amazon.com/Implementation-Patterns-Addison-Wesley-Signature-Kent/dp/0321413091[/quote]

A casos e casos… neste exemplo realmente não faz necessario o uso de um setter… pois o proprio objeto pode muder seu estado… porem qdo necessitamos de uma interação entre objetos, uma representação das entidades? como javabeans por exemplo… dai sim faz sentido…

[quote=rodrigoy]Não uso essa nomenclatura ‘Repositorio’.

Como citaram aqui, repositórios possuem assinaturas de Collection. Devem atuar como tal.[/quote]

Rodrigoy, o que eu quero dizer, sobre essa sua nomenclatura é o seguinte: TodosQuartos ou TodasReservas não me dá a idéia de uma coleção, de uma lista, de um repositório, enfim, de um objeto… me dá a idéia de vários objetos ao mesmo tempo. Tudo bem em mandar um objeto executar uma ação, mas vários objetos ao mesmo tempo soa meio desconfortável à leitura. Olha só:

ListaDeQuartos.getDisponiveis(periodo) ok, pois leio "hey lista de quartos, me dê os disponíveis no periodo tal."
ColecaoDeQuartos.getDisponiveis(periodo) ok, pois leio "hey coleção de quartos, me dê os disponíveis no periodo tal."
RepositorioDeQuartos.getDisponiveis(periodo) ok, pois leio "hey repositório de quartos, me dê os disponíveis no periodo tal."
TodosQuartos.getDisponiveis(periodo) estranho, pois leio “hey todos os quartos, me dê os disponíveis no periodo tal.”

Por outro lado, TodosQuartos.disponiveisEm(periodo) ok, pois leio “quero todos os quartos disponíveis em tal periodo.”

Não estou encrencando com a sua escolha de nome do repositório, que por sinal é bem melhor do que todas as outras alternativas. Estou dizendo que o nome dos métodos que voce escolheu causam (ao menos a mim) um pouco de desconforto na leitura. Isso sem falar nesse ‘get’, que como já falei, parece um feijão no dente da ubiquitous language.

Pelo jeito o assunto aqui disvirtuou… começou em Repositorios e terminou em nomeclaturas…

[quote=rodrigoy]
PersonRepository, PessoaRepository, PessoaRepositorio não faz sentido para as pessoas do domínio. Esse é o meu ponto. WholeCars não faz sentido. Estamos dando exemplos em português.[/quote]

Talvez InformacoesDePessoas, InformacoesDeQuartos, InformacoesDeReservas, não sei, ainda está estranho…

[quote=boaglio][quote=rodrigoy]
PersonRepository, PessoaRepository, PessoaRepositorio não faz sentido para as pessoas do domínio. Esse é o meu ponto. WholeCars não faz sentido. Estamos dando exemplos em português.[/quote]

Talvez InformacoesDePessoas, InformacoesDeQuartos, InformacoesDeReservas, não sei, ainda está estranho… [/quote]

Eu acho que o nome Reservas, funciona melhor do que TodasReservas, me parece mais intuitivo.

E a consulta de quartos disponiveis deveria estar em Reservas.

Reservas reservas = new ReservasImpl(...); List<Quarto> reservas.getQuartosDisponiveis(Periodo periodo) {...}

Um quarto não sabe se está disponivel ou não, para saber se está disponivel tem de ver se no periodo tem alguma reserva feita, se tiver não está disponivel.

Sergio, dei as alternativas mais para facilitar a reflexão.

Apesar de ser uma solução plausível, “reservas possíveis” é um termo novo do domínio. Creio que feriria a UL. Mas você concorda então que a responsabilidade é das reservas. Certo?

Edufa, é uma alternativa. Eu já usei… ficou melhor que ReservaRepositorio, mas por alguma razão, descartei essa nomenclatura. Acho que é por ser muito próximo do nome da entidade e alguns nomes ficam estranhos.

[quote=viniciusv]
Não estou encrencando com a sua escolha de nome do repositório, que por sinal é bem melhor do que todas as outras alternativas. Estou dizendo que o nome dos métodos que voce escolheu causam (ao menos a mim) um pouco de desconforto na leitura. Isso sem falar nesse ‘get’, que como já falei, parece um feijão no dente da ubiquitous language.[/quote]

Vinicius… meus repositórios são JavaBeans, pois uso muito DDD com JBoss Seam e não tenho preconceito de usá-los (meus repositórios) diretamente na UI. Algo como:

#{todasCategorias.ativas}

TodasCategorias.getAtivas()

Mas fique à vontade de usar de outras maneiras. Não fere muito o conceito que preguei aqui.

(gostei desse termo… um feijão no dente da UL) :wink:

Meu repositório pode ser um Javabean se eu decidir que sim, certo? (leia meu post anterior)

[quote] sergiotaborda wrote:
A ideia do viniciusv é válida porque disponíveis não é uma propriedade de TodosOsQuartos porque esse objeto não é um bean , nem um javabean , nem um (entity) EJB : ou seja, ele não tem propriedades logo ele não têm get/set .

Meu repositório pode ser um Javabean se eu decidir que sim, certo? (leia meu post anterior)[/quote]

Mesmo porque, falando em OO, qualquer objeto tem propriedades. Independente de bean, javabean ou seja lá o que for!

[quote=rodrigoy][quote=sergiotaborda]
A ideia do viniciusv é válida porque disponíveis não é uma propriedade de TodosOsQuartos porque esse objeto não é um bean , nem um javabean , nem um (entity) EJB : ou seja, ele não tem propriedades logo ele não têm get/set .
[/quote]

Meu repositório pode ser um Javabean se eu decidir que sim, certo? (leia meu post anterior)[/quote]

Antes de mais é preciso cuidar o fato que JavaBean é um nome especial ( se escreve até com TM).
ELe designa uma tecnologia em que o objeto tem propriedades e além disso ele tem listenerts para alteração dessas propriedades. O SwingBeans, por exemplo, tira partido desta tecnologia.

Um objeto só com get/set mas sem o mecanismo de listeners não é um javabean. (Um entity ejb 3 não é um javabean)
Um objeto com listeners que não sejam para a alteração das propriedades não são javabeans.

O seu repositório têm propriedades ?

  • se sim, então ele pode ter propriedades e listeners e virar um javabean
  • se não, não ha como ser um javabean

Os meus não têm. Se os seus têm, por favor dê um exemplo que fiquei curioso.

Se vc nunca viu isso, então é dificil aceitar que possam ser javabeans.

[quote=rodrigoy]
Apesar de ser uma solução plausível, “reservas possíveis” é um termo novo do domínio. Creio que feriria a UL. Mas você concorda então que a responsabilidade é das reservas. Certo?[/quote]

Com certa a responsabilidade é de quem conseguir procurar quartos e datas. Essas coisas são reservas, então não tem como fugir que o respositorio seja o de reservas. Mas, o retorno não pode ser quartos. Esse , acho, que é o ponto mais importante.

Não acho que reservas possiveis seja um novo termo, mas mesmo que seja, ele não é uma nova entidade, logo o dominio não mudou. Por outro lado, sem adicionar esse novo conceito não ha como resolver o problema que vc propos dentro do SoC.

Claro que vc pode sempre usar TodasReservas.getReservas(Periodo) para não incluir o novo termo …

Na prática, eu acho, vc chegaria na conclusão logica que é preciso esse conceito e vc propunha isso para o cliente. E ai , ou ele confirma que é isso mesmo ou ele propoe uma alternativa coerente. Por exemplo, ele pode achar que fica melhor : TodasReservas.getReservasAbertas(Periodo).

Acho que a palavra final para o sufixo é irrelevante. Ele vai vir naturalmente da conversa com o cliente e ser adicionado ao UL. O ponto da analise é descobrir que esse sufixo é necessário (aka essa “categoria” de reservas).

Da sua resposta parece que não ha espaço para adicionar coisas à UL atual. Acho que isso não é a realidade prática já que o processo é inerentemente interativo e iterativo.

Vc tem razão, meus repositórios não tem listeners e não vejo razões para ter listeners…

(para falar a verdade, isso deveria ser out-of-the-box no Java)

Um repositório poderia ser um Javabean numa aplicação desktop local.