| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/12/2008 21:16:44
|
hlegius
JavaChild
![[Avatar]](/images/avatar/0f20c77d6afb02422603acb0329b5a41.jpeg)
Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline
|
Salve turma !
Estou criando um modelo aqui porém surgiram algumas dúvidas que gostaria de tirar com os senhores.
Abaixo tem o diagrama de classes:
A idéia seria realizar as tarefas:
- Através da classe Cliente eu poderia descobrir os pedidos realizados pelo tal Cliente usando o Clientes.getPedidos(). Esse cara me retornaria um array contendo os Pedido(s).
Dúvida: eu coloquei o Pedido como composição de Clientes, com isso eu não teria um Pedido andando sozinho pelo sistema. (tem até uma certa lógica, certo ?) Porém, se eu precisar de um relatório de todos Pedidos pagos já era, pois os pedidos estão atrelados a cada Cliente.
Pensei em usar algo como um Serviço para resgatar esses pedidos, mas eu não vi muita "relação" entre o Serviço Pedido "perdido" na aplicação.
- A classe CarrinhoCompras irá conter os Produto(s) adicionados à cesta até o momento. Qualquer um pode adicionar, cliente ou não. Porém, para utilizar o método CarrinhoCompra.registraCompra() o usuário precisa estar autenticado, para que o CarrinhoCompra delegue a tarefa de finalizar o pedido à classe Pedido (ao meu ver tem sentido essa relação)
Dúvida: no CarrinhoCompras.adiciona() eu irei persistir o produto em sessão. Neste caso, o próprio carrinho persiste isto, tipo um ActiveRecord. Eu acho que neste caso, o AR cairia bem, o que acham ?
Dúvida2: a delegação de CarrinhoCompra.registraCompra() para Pedido.registraCompra(carrinho) penso ter sentido, até porque ninguém mais esperto para controlar o Pedido do que o próprio pedido e em contra partida, o CarrinhoCompra.registraCompra() após delegar a tarefa e recebendo um "sinal" positivo, poderia por exemplo limpar o carrinho. O que acham ? Eu talvez pudesse chamar diretamente o Pedido.registraCompra() na Action/Controladora. Daí a dúvida.
- A classe Produto se relaciona usando agregação com Pedido e com CarrinhoCompra. Aqui não tem problemas.
No geral, penso que para o Cliente seria interessante ter um Serviço enquanto que Pedido e CarrinhoCompras seriam persistidos usando ActiveRecord e acessados diretamente na minha Action.
Aqui no GUJ já vi gente defendendo o uso de Services sempre que for possível. Só que nesse meu raciocinio - limitado ainda X) - eu não vejo porquê acessar Pedido via Serviço (ele existir fora do Cliente).
E no caso de Relatórios de Pedidos eu poderia chamar o Repositório do Pedido diretamente na Action. Ou seria isto "um pecado" ?
O que vocês pensam sobre tudo isto ?
Abraços!
This message was edited 1 time. Last update was at 01/12/2008 21:17:29
|
http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/12/2008 21:38:57
|
Adolfo Rodrigues
Java Ninja
![[Avatar]](/images/avatar/5c9dc137c4e9543d7e4001d7bdef7413.jpg)
Membro desde: 18/04/2007 20:02:52
Mensagens: 270
Localização: Sampa
Offline
|
Não sei se vou te ajudar ou te confundir mais um pouco, mas você já pensou em fazer a modelagem destas classes com TDD? Acho que este é um caso claro em que um design evolutivo se aplica muito bem. Tenho certeza de que esta estratégia te ajudaria, por exemplo, a encapsular melhor os pedidos e evitar coisas como
Através da classe Cliente eu poderia descobrir os pedidos realizados pelo tal Cliente usando o Clientes.getPedidos(). Esse cara me retornaria um array contendo os Pedido(s)
TDD ajuda muito na construção de um design limpo e elegante. Acho que você deveria considerar esta alternativa...
|
http://www.adolfosousa.com.br/blog |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 07:39:16
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
Adolfo Rodrigues wrote:Não sei se vou te ajudar ou te confundir mais um pouco, mas você já pensou em fazer a modelagem destas classes com TDD?
Acho que vc está confundindo demais ... O problema é claramente de modelagem. Onde raios os testes vão ajudar o cara se ele não sabe como desenhar o sistema ? vc acha que por tentativa e erro ele vai conseguir uma epifania ? Eu duvido...
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 07:48:57
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
hlegius wrote:
- Através da classe Cliente eu poderia descobrir os pedidos realizados pelo tal Cliente usando o Clientes.getPedidos(). Esse cara me retornaria um array contendo os Pedido(s).
Ok, mas use uma coleção. Não use arrays!
Dúvida: eu coloquei o Pedido como composição de Clientes, com isso eu não teria um Pedido andando sozinho pelo sistema. (tem até uma certa lógica, certo ?)
A ideia está certa mas o digrama errado. O diamante preto é do lado do pedido, não do cliente. Além disso faltam quantificadores em todo o modelo.
Porém, se eu precisar de um relatório de todos Pedidos pagos já era, pois os pedidos estão atrelados a cada Cliente.
Pensei em usar algo como um Serviço para resgatar esses pedidos, mas eu não vi muita "relação" entre o Serviço Pedido "perdido" na aplicação.
Tlv não vcnão viu agora, mas essa é a forma mais acertada. O pedido não pode ser responsável pela operações sobre ele. É mais ao menos como vc ser responsável pela sua educação. Se isso funcionasse não existam professores. ...
Dúvida: no CarrinhoCompras.adiciona() eu irei persistir o produto em sessão. Neste caso, o próprio carrinho persiste isto, tipo um ActiveRecord. Eu acho que neste caso, o AR cairia bem, o que acham ?
acho que vc eastá viajando... O objecto CarrinhoDeCompras é que existe na sessão. O objecto lá dentro não precisa persistir nada em lugar nenhum.
Dúvida2: a delegação de CarrinhoCompra.registraCompra() para Pedido.registraCompra(carrinho) penso ter sentido, até porque ninguém mais esperto para controlar o Pedido do que o próprio pedido e em contra partida, o
A sua frase equivale a "ninguem mais esperto para controlar uma cirurgia ao coração que o proprio dono do coração"
Isso está errado. A compra/venda é uma outra entidade do sistema. Porque o pedido seria capaz ou responsável de manipular essa entidade ? A manipulação conjunta de 2 ou mais entidades indica a necessidade de um serviço ( que já tinha sido indicado na primeira duvida)
No geral, penso que para o Cliente seria interessante ter um Serviço enquanto que Pedido e CarrinhoCompras seriam persistidos usando ActiveRecord e acessados diretamente na minha Action.
Aqui no GUJ já vi gente defendendo o uso de Services sempre que for possível. Só que nesse meu raciocinio - limitado ainda X) - eu não vejo porquê acessar Pedido via Serviço (ele existir fora do Cliente).
É como não ver a vantagem de escover os dentes todos os dias, mas ao final de vários anos vc entende a vantagem.
use o serviço. Vc mesmo chegou na conclusão que precisa dele, mas está resistindo. É muito mais simples que ficam gambiarrando o sistema.
E no caso de Relatórios de Pedidos eu poderia chamar o Repositório do Pedido diretamente na Action. Ou seria isto "um pecado" ?
Sim. qualquer coisa que seja logica de negocio/dominio que aconteça numa action é um pecado.
Vc cria uma outra classe. Vc passa a ela os parametros e ela gera o report. A action recebe esse report e mostra. Só isso.
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 08:06:32
|
Adolfo Rodrigues
Java Ninja
![[Avatar]](/images/avatar/5c9dc137c4e9543d7e4001d7bdef7413.jpg)
Membro desde: 18/04/2007 20:02:52
Mensagens: 270
Localização: Sampa
Offline
|
sergiotaborda wrote:Acho que vc está confundindo demais ... O problema é claramente de modelagem. Onde raios os testes vão ajudar o cara se ele não sabe como desenhar o sistema ? vc acha que por tentativa e erro ele vai conseguir uma epifania ? Eu duvido...
Sim, eu entendi que o problema é de modelagem. Por isso escrevi "mas você já pensou em fazer a modelagem destas classes com TDD?". TDD é pra modelar; você ganha os testes de presente. E sim, eu continuo achando que modelar evolutivamente e usando TDD é muito mais fácil e tem resultados melhores.
|
http://www.adolfosousa.com.br/blog |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 09:49:59
|
hlegius
JavaChild
![[Avatar]](/images/avatar/0f20c77d6afb02422603acb0329b5a41.jpeg)
Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline
|
sergiotaborda wrote:Ok, mas use uma coleção. Não use arrays!
Sem dúvidas. Apenas me expressei de forma errada =(
sergiotaborda wrote:A ideia está certa mas o digrama errado. O diamante preto é do lado do pedido, não do cliente. Além disso faltam quantificadores em todo o modelo.
Sério mesmo que o diamante é do lado oposto ? hahahaha... eu jurava que estava certo. Se for assim acho que tá tudo invertido então !
Ao menos a minha idéia do "Pedido não poder andar sozinho" faz sentido.
sergiotaborda wrote:acho que vc eastá viajando... O objecto CarrinhoDeCompras é que existe na sessão. O objecto lá dentro não precisa persistir nada em lugar nenhum.
Mas se eu persistir o objeto CarrinhoCompras em sessão, quem irá controlar esta sessão ? Digo, trazer o CarrinhoCompras devolta para por exemplo, adicionar mais um item à cesta ? Eu estava pensando em fazer os atributos deste carrinho serem salvos em sessão e o próprio CarrinhoCompras controlar essas sessões, entende ?
sergiotaborda wrote:A sua frase equivale a "ninguem mais esperto para controlar uma cirurgia ao coração que o proprio dono do coração"
Isso está errado. A compra/venda é uma outra entidade do sistema. Porque o pedido seria capaz ou responsável de manipular essa entidade ? A manipulação conjunta de 2 ou mais entidades indica a necessidade de um serviço ( que já tinha sido indicado na primeira duvida)
Realmente, pensando dessa forma fica estranho mesmo.
Pensando com calma agora, eu vejo que o Cliente poderia finalizar esta compra. Entretanto, seria mesmo estranho um Cliente.finalizarCompra(). Então, penso que seria interessante ter uma classe que ficasse responsável pela entidade Pedido e essa classe, receberia a coleção de produtos e o cliente para finalizar a compra.
Algo como:
sergiotaborda wrote:É como não ver a vantagem de escover os dentes todos os dias, mas ao final de vários anos vc entende a vantagem.
use o serviço. Vc mesmo chegou na conclusão que precisa dele, mas está resistindo. É muito mais simples que ficam gambiarrando o sistema.
Não sou contra ele. Apenas tenho receio de colocar o Serviço em Pedido e acabar fazendo ele (Pedido) ficar "desacoplado" do Cliente. Em outras palavras, criando o ServiçoPedido eu não estaria fazendo meu Pedido ser acessível por qualquer um em qualquer parte da aplicação ?
Porque se não for algo que vá deixar o Pedido viajando sem rumo pela aplicação, eu poderia criar o ServiçoPedido e centralizar as tarefas nele. Neste caso, o Cliente.getPedidosFinalizados() iria solicitar ao ServicoPedido.listaFinalizados(), ou não ?!
sergiotaborda wrote:Sim. qualquer coisa que seja logica de negocio/dominio que aconteça numa action é um pecado.
Vc cria uma outra classe. Vc passa a ela os parametros e ela gera o report. A action recebe esse report e mostra. Só isso.
Entendido.
"outra classe" = Serviço ?
Adolfo Rodrigues wrote:TDD ajuda muito na construção de um design limpo e elegante. Acho que você deveria considerar esta alternativa...
Desenvolvimento Orientado à testes eu irei aprender um dia. Por hora estou limitando-se ao design OO mesmo para tentar entender como as coisas funcionam. Acho que eu parar para pegar sobre TDD iria dar um nó ainda maior. Apenas "acho" porque nunca li muito sobre TDD =( Ainda estou começando a ler sobre DDD - consegui comprar o Livro do Eric Evans \o/.
Mas irei guardar a dica ! Isso acaba me deixando mais interessado sobre TDD e Agile =)
Abraço a todos !
|
http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 11:45:52
|
YvGa
Virtual Machine Man
Membro desde: 07/03/2007 15:58:16
Mensagens: 517
Offline
|
So pra me meter na discussao sobre TDD:
Nao tenho nada contra um pouco de design ja de inicio. Um esboco pra se ter nocao do relacionamento das entidades, pra se ter uma visualizacao geral desses relacionamentos. Se for preciso, faca. Mas nao se aprofunde, nao tente visualizar detalhes da implementacao que vc vai estar jogando tempo, o que é precioso, pela janela. 90% das vezes, quando vc for implementar o que esta diagramado voce vai enxergar formas melhores de fazer. É nesse ponto que entra TDD, vc escreve os testes dessas funcionalidade, e soh o fato de escrever os testes ja te dá uma boa nocao sobre o que e como essa funcionalidade vai fazer.
Se esse for um projeto real, com prazo bem definido, o que normalmente significa curto. Faca do jeito que sabe e entregue dentro do prazo. Voce vai poder ajustar depois, muitas vezes nao eh tao complexo quanto parece.
Se for um projeto de aprendizado nao ha hora melhor pra dar uma olhada em TDD. Nao se preocupe, ele em nada conflita com DDD, pelo contrario.
O conceito de TDD eh simples e nao exige um estudo de 1000 paginas sobre um milhao de patterns. Mas eh uma tecnica de desenvolvimento diferente das formas habituais e que exige muita disciplina do desenvolvedor. Ela pode ajudar sim na construcao de um modelo mais elegante. Só é preciso cuidado pra que nao vire um caos, e o desenvolvedor pense que pode sair escrevendo codigos pra todo lado, sem um rumo definido.
Resumindo, o conceito é simples, a pratica nem tanto. Se voce tiver tempo nesse projeto eu recomento, porque alem de ser util é divertido.
|
Paulo Borio |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 16:04:28
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
hlegius wrote:
sergiotaborda wrote:acho que vc eastá viajando... O objecto CarrinhoDeCompras é que existe na sessão. O objecto lá dentro não precisa persistir nada em lugar nenhum.
Mas se eu persistir o objeto CarrinhoCompras em sessão, quem irá controlar esta sessão ? Digo, trazer o CarrinhoCompras devolta para por exemplo, adicionar mais um item à cesta ? Eu estava pensando em fazer os atributos deste carrinho serem salvos em sessão e o próprio CarrinhoCompras controlar essas sessões, entende ?
eu entendo, mas não acho certo. quem vai por e tirar o carrinho da sessão tem que ser um objeto com acesso à sessão . O mais obvio é o action, mas vc pode criar um terceiro objecto que encapsula o acesso à sessão ( mas acho que isso é over kill)
sergiotaborda wrote:É como não ver a vantagem de escover os dentes todos os dias, mas ao final de vários anos vc entende a vantagem.
use o serviço. Vc mesmo chegou na conclusão que precisa dele, mas está resistindo. É muito mais simples que ficam gambiarrando o sistema.
Não sou contra ele. Apenas tenho receio de colocar o Serviço em Pedido e acabar fazendo ele (Pedido) ficar "desacoplado" do Cliente. Em outras palavras, criando o ServiçoPedido eu não estaria fazendo meu Pedido ser acessível por qualquer um em qualquer parte da aplicação ?
E qual é o problema disso ?
Os pedidos sim têm que ser acessados em qualquer lugar. São classes publicas, não são ?
Porque se não for algo que vá deixar o Pedido viajando sem rumo pela aplicação, eu poderia criar o ServiçoPedido e centralizar as tarefas nele. Neste caso, o Cliente.getPedidosFinalizados() iria solicitar ao ServicoPedido.listaFinalizados(), ou não ?!
Se vc fizer bem feito não vai ficar viajando à toa. Mas viajar faz parte
sergiotaborda wrote:Sim. qualquer coisa que seja logica de negocio/dominio que aconteça numa action é um pecado.
Vc cria uma outra classe. Vc passa a ela os parametros e ela gera o report. A action recebe esse report e mostra. Só isso.
Entendido.
"outra classe" = Serviço ?
Poderia.
Poderia ser só um repositorio tb. Depende do que é o seu objeto de report.
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/12/2008 19:35:07
|
hlegius
JavaChild
![[Avatar]](/images/avatar/0f20c77d6afb02422603acb0329b5a41.jpeg)
Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline
|
sergiotaborda wrote:eu entendo, mas não acho certo. quem vai por e tirar o carrinho da sessão tem que ser um objeto com acesso à sessão . O mais obvio é o action, mas vc pode criar um terceiro objecto que encapsula o acesso à sessão ( mas acho que isso é over kill)
Entendi seu ponto de vista. A mais fácil serializar o objeto CarrinhoCompra todo e trabalhar a serialização/deserialização na Action mesmo para evitar problemas e over kill.
sergiotaborda wrote:E qual é o problema disso ?
Os pedidos sim têm que ser acessados em qualquer lugar. São classes publicas, não são ?
No meu entendimento, dando ao pedido a possibilidade de "ter vida" sozinho, a aplicação perderia o sentido. Eu pensei na Cliente ¹<composicao>----* Pedido porque em teoria só existe Pedidos se houver clientes. Mas eu estou vendo que não é preciso seguir isto tão ao pé-da-letra [..]
Então, tendo em vista as dicas que venho recebendo, vamos tentar outro modelo:
(Agora com quantificadores =])
Conforme me sugeriu, coloquei um Serviço para o pedido, assim, eu consigo trabalhar com Pedido em mais de um lugar (como você mesmo disse mais acima). O Cliente talvez também tenha seu Serviço. O Carrinho tem lá suas relações com Cliente e Produto(s) normalmente.
A única coisa que não fiz nesse diagrama foi a relação Pedido - Cliente. Eu penso que seria ideal ter a relação: Cliente.getPedidos() retornar uma collection de Pedido. Isso é trabalho do Repositório, penso. Ele que ao buscar a collection de clientes traria (caso eu pedisse) os pedidos desses clientes também, correto ?
sergiotaborda wrote:Poderia.
Poderia ser só um repositorio tb. Depende do que é o seu objeto de report.
Hum. Se o meu report fosse útil para vários fins, seria interessante encapsular isto num Service, do contrário poderia manter só o Repositório, seria isto ?
Agradeço a ajuda!
|
http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/12/2008 03:51:55
|
djemacao
GUJ Master
Membro desde: 04/06/2007 17:47:24
Mensagens: 1030
Offline
|
Bom, seguinte, seu UML está esquisito.
O Cliente tem que estar ligado ao Pedido. Afinal, quem faz o pedido?
Seu diagrama teria que ter um ItensDoPedido, subordinado ao pedido, contendo os produtos comprados, qtd, preco da compra, desconto e outros. O Carrinho de compras necessita apenas colecionar os itens de um pedido, ou seja, quando finalizá-lo, ele vai enviar as informações para os ItensDoPedido.
|
"Quanto mais aprendo mais tenho consciência que nada sei." |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/12/2008 10:43:15
|
hlegius
JavaChild
![[Avatar]](/images/avatar/0f20c77d6afb02422603acb0329b5a41.jpeg)
Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline
|
Opa !
djemacao wrote:Bom, seguinte, seu UML está esquisito.
O Cliente tem que estar ligado ao Pedido. Afinal, quem faz o pedido?
Seu diagrama teria que ter um ItensDoPedido, subordinado ao pedido, contendo os produtos comprados, qtd, preco da compra, desconto e outros. O Carrinho de compras necessita apenas colecionar os itens de um pedido, ou seja, quando finalizá-lo, ele vai enviar as informações para os ItensDoPedido.
Sim. No primeiro diagrama eu tentei essa relação (Pedido depende de Cliente para existir), já no segundo, após tentar seguir as dicas do pessoal, eu acabei por não fazendo essa relação, uma vez que foi falado que o Pedido pode sim existir fora do escopo da classe Cliente - para relatórios por exemplo - daí acabei ficando na dúvida em como fazê-la corretamente.
Eu entendo que para persistir as infos no banco de dados, eu precisaria de uma tabela adicional para relacionar corretamente o Pedido com os itens do pedido, porém, não vi necessidade em criar uma classe adicional para cuidar dos itens. A própria Pedido não pode conter uma coleção dos itens (Produto) comprados ?
Agradeço a ajuda !
|
http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/12/2008 11:33:36
|
YvGa
Virtual Machine Man
Membro desde: 07/03/2007 15:58:16
Mensagens: 517
Offline
|
Eu entendo que para persistir as infos no banco de dados, eu precisaria de uma tabela adicional para relacionar corretamente o Pedido com os itens do pedido, porém, não vi necessidade em criar uma classe adicional para cuidar dos itens. A própria Pedido não pode conter uma coleção dos itens (Produto) comprados ?
A principio parece logico pedido ter uma lista de produtos. Mas onde ficariam as informacoes com relacao a quantidade, preco de venda (especifico desse pedido, que pode ser diferente no pedido, e sera com certeza quando mudar o preco do produto). Voce muito provavelmente vai precisar de uma classe para guardar as informacoes que nao estarao nem no pedido nem no produto.
|
Paulo Borio |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/12/2008 12:53:43
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline
|
hlegius wrote:
sergiotaborda wrote:E qual é o problema disso ?
Os pedidos sim têm que ser acessados em qualquer lugar. São classes publicas, não são ?
No meu entendimento, dando ao pedido a possibilidade de "ter vida" sozinho, a aplicação perderia o sentido. Eu pensei na Cliente ¹<composicao>----* Pedido porque em teoria só existe Pedidos se houver clientes. Mas eu estou vendo que não é preciso seguir isto tão ao pé-da-letra [..]
Vc está misturando as coisas. Do ponto de vista logico um pedido é feito por um cliente e não ha como criar pedidos sem cliente.
Ok. Isso é a relação de agregação que já tinha. Isso não tem nada a haver como eu pode manipular o objeto Pedido. Apenas está relacionado à criação do objeto ( o construtor precisa de um Cliente).
Agora, uma vez criado, o pedido tem sempre um cliente associado. Contudo eu não preciso consultar esse cliente a todo o momento.
Eu preciso de 2 coisas além do objeto Pedido. Um objeto que saiba criar pedidos e um objeto que saiba procurar pedidos.
O segundo é um repositorio de pedidos. O primeiro é um Serviço.
E isto é verdade para qualquer entidade.
O Seriço de cliente não serve para consultar os clientes dos sistema (geClientes). Ele serve para manipular o cliente.
A sua classe ClienteServiço é na realidade um RepositorioDeCliente. É lá onde vc armazena e procura os clientes.
O mesmo para o PedidoServiço.
O serviço seria uma classe assim :
O carrinho de compras já tem o cliente. Em um sistema real noramlmente o carrinho é genérico e só é atrelado ao cliente quando o usuário diz que quer transformar o carrinho em pedido a interface seria melhor assim
Este serviço faz várias coisas. Ele verifica se o carrinho tem produtos. Se os produtos tem estoque.
Cria um objeto pedido para o cliente ( Pedido p = new Pedido(cliente)) adiciona os itens do pedido conforme o carrinho de compras indica ( quantidades, etc.. ) Adiciona promoções ao pedido, descontos, etc... e coloca o pedio em um certo estado dentro do ciclo de vida do pedido. Provávelmente ele tb salva o pedido repositórios de pedidos para garantia.
depois de tudo isso existe um pedido. Ok, e agora?
Agora aplicação pode pedir dados do cartão de crédito, por exemplo. Validar, etc. Isso será feito pelo ServiçoDeVerificaçãoDeVenda ou algo assim. Depois disso o pedido muda de estado. Agora um processo será ativado para levar os produtos ao cliente.
então , um serviço é algo que aplicação sabe fazer / precisa fazer. É dentro dele que estão as lógicas do negocio e são eles que vc altera quando a logica muda. Um serviço pode conversar com outros serviços ( por exemplo ServiçoDeDesconto que dá descontos ao cliente conforme o seu historico, ou perfil, ou campanha de marketing etc.. )
Repositórios são apenas depositos. Depositos espertos, mas não inteligentes. Ou seja, vc tem um método para procurar pedidos cancelados para um certo cliente, vc tem métodos para procurar pedidos não finalizados, já entregues, feitos em certa data ,etc.. ou seja, vc tem métodos que os serviços irão utilizar para encontrar todos os pedidos em um certo critério.
O seu modelo básicamente mostra entidades e repositorios ( embora vc os chame de serviços, eles não são serviços realmente). métodos como "registraCompra" terão que ser colocados como serviços.
A única coisa que não fiz nesse diagrama foi a relação Pedido - Cliente. Eu penso que seria ideal ter a relação: Cliente.getPedidos() retornar uma collection de Pedido. Isso é trabalho do Repositório, penso. Ele que ao buscar a collection de clientes traria (caso eu pedisse) os pedidos desses clientes também, correto ?
sim.
Vc pode ter um repositorio de Pedidos com o método encontraTodosPedidosPara(Cliente cliente): List<Pedido>
Um serviço poderia usar isso trnaquilamente. O Cliente poderia usar tb assim
Esta abordagem é legal, mas é limitada. Vc não vai criar um getPedidosXXX() em Cliente para cada opção possivel de estado , tipo, tamanho, data, etc.. do pedido. Básicamente vc cliente.getPedidos deve trazer todos os pedidos que existem para o cliente.
O ponto é: Repositorios são mais uteis. entidades podem usar repositorios, mas não é bom poluir a interface da entidade com métodos de pesquisa especializada. Isso é função do repositorio.
sergiotaborda wrote:Poderia.
Poderia ser só um repositorio tb. Depende do que é o seu objeto de report.
Hum. Se o meu report fosse útil para vários fins, seria interessante encapsular isto num Service, do contrário poderia manter só o Repositório, seria isto ?
Não.
Se o seu "relatorio" é apenas um list de objetos pedido vc pode usar o repositorio e fazer repositorio.encontraPedidosParaRelatorio1().
Mas isso implica ter vários métodos no repositorio. Mas é legal para pequenos repatorios.
O ideal é vc ter um objeto ProductReportService ou algo assim e ter lá os métodos. internamente esses métodos pode requisitar mais do que uma informação ao repositorio e fazer liogicas de filtro, agrupamento etc que o repositorio não faz.
Mesmo que o report só tenha uma finalidade é bom encapsular a sua criação em um objeto.
Agora imagine que o seu report é um objeto Report (por exemplo um objeto do jasperReport) , ele não é uma lista.
Ele já contém layout de apresentação e tudo. O seu ProductReportService irá criar esse objeto e depois outro objeto irá converter isso em HTML para mostrar na tela, ou PDF para download, etc... ( é claro que com List isto tb funciona, mas é só para deixar claro que um Report pode ser mais do que uma lista de dados- tem titulo , etc... )
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/12/2008 15:27:32
|
Marcio Duran
GUJ Master
![[Avatar]](/images/avatar/df0e19d29493ef2136fc3e2fc029c054.jpg)
Membro desde: 23/01/2008 11:14:35
Mensagens: 1905
Offline
|
sergiotaborda wrote:
O ponto é: Repositorios são mais uteis. entidades podem usar repositorios, mas não é bom poluir a interface da entidade com métodos de pesquisa especializada. Isso é função do repositorio.
Sergio poderia dar maior visibilidade nessa colocação "interface da entidade com método de pesquisa", a quem você esta atribuindo pesquisa, um façade "não entendi"
This message was edited 2 times. Last update was at 03/12/2008 15:29:00
|
Consultor Open Source
Comunidade JavaLivros
Twitter Comunidade JavaLivros
Novo Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/12/2008 18:40:01
|
hlegius
JavaChild
![[Avatar]](/images/avatar/0f20c77d6afb02422603acb0329b5a41.jpeg)
Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline
|
sergiotaborda wrote:Vc está misturando as coisas. Do ponto de vista logico um pedido é feito por um cliente e não ha como criar pedidos sem cliente. Ok. Isso é a relação de agregação que já tinha. Isso não tem nada a haver como eu pode manipular o objeto Pedido. Apenas está relacionado à criação do objeto ( o construtor precisa de um Cliente).
Huum ! Entendi agora. Pensei que não pudesse de forma nenhuma ter seu próprio serviço e etc. Mas é diferente. Toda vez que ele for requisitado, estará "acompanhado" de um Cliente.
sergiotaborda wrote:Eu preciso de 2 coisas além do objeto Pedido. Um objeto que saiba criar pedidos e um objeto que saiba procurar pedidos. O segundo é um repositorio de pedidos. O primeiro é um Serviço.
Certo. Então o cara que aplica regras de negócio é o Serviço da entidade. Ele executa alguma tarefa - algum "serviço" - e pronto. Certo. O serviço pode comunicar-se com seu Repositório para persistir alguma informação tranquilamente, correto ?
sergiotaborda wrote:Isso será feito pelo ServiçoDeVerificaçãoDeVenda ou algo assim. Depois disso o pedido muda de estado.
Esse suposto "serviço" irá pegar o número do cartão, conectar-se à um webservice e validar a compra, ao tentar mudar o "estado" do pedido ele deverá solicitar a mudança ao ServiçoPedido (algo que seria o mais correto [centralizar coisas]) ao invés dele mesmo(ServiçoDeVerificaçãodeVenda) realizar a mudança de estado do pedido. Em outras palavras:
sergiotaborda wrote:O seu modelo básicamente mostra entidades e repositorios ( embora vc os chame de serviços, eles não são serviços realmente). métodos como "registraCompra" terão que ser colocados como serviços.
Então as entidades deverão apenas conter rotinas que cabem a elas mesmo fazerem, como chegar seus próprios dados, comparações de dados recebidos com dados em memória. Serviços trabalham essas entidades. Tratam as informações, fazem checagens - Às vezes usando métodos da própria entidade, às vezes consultando outros Serviços e por fim o Repositório que está lá para buscar entidades persistidas para auxiliar o serviço em algo, ou simplemente para exibi-las ao usuário. Resumão correto ?
sergiotaborda wrote:O ponto é: Repositorios são mais uteis. entidades podem usar repositorios, mas não é bom poluir a interface da entidade com métodos de pesquisa especializada. Isso é função do repositorio.
Se o repositório é o cara que faz isto bem - e você já me explicou como ele faz isto =) - onde eu poderei chamá-lo para trazer estes resultados ? Se o ServiçoX precisar de dados do Repositório, ele pode e deve chamá-lo. Legal, mas e se o Serviço não precisar ? Vamos supor que eu simplemente queira exibir na tela os Pedidos finalizados do mês 11. Então eu iria fazer: Mas onde eu poderia chamá-lo, se na Action você disse-me que não seria legal entupi-la de chamadas à repositórios ?
sergiotaborda wrote:O ideal é vc ter um objeto ProductReportService ou algo assim e ter lá os métodos. internamente esses métodos pode requisitar mais do que uma informação ao repositorio e fazer liogicas de filtro, agrupamento etc que o repositorio não faz.
Maneiro. Os serviços servem para um bocado de tarefas =) Já vi gente comentando sobre Serviços estáticos. Seria isto interessante ?
sergiotaborda wrote:Mesmo que o report só tenha uma finalidade é bom encapsular a sua criação em um objeto. Agora imagine que o seu report é um objeto Report (por exemplo um objeto do jasperReport) , ele não é uma lista. Ele já contém layout de apresentação e tudo. O seu ProductReportService irá criar esse objeto e depois outro objeto irá converter isso em HTML para mostrar na tela, ou PDF para download, etc... ( é claro que com List isto tb funciona, mas é só para deixar claro que um Report pode ser mais do que uma lista de dados- tem titulo , etc... )
Isto inclusive é uma boa prática OO ao que vi em livros =) Abraços!
This message was edited 1 time. Last update was at 03/12/2008 18:40:24
|
http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution |
|
|
 |
|
|
|
|