hlegius:
"sergiotaborda":
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 ¹----* 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 :
interface ServiçoDePedidos {
public Pedido criaPedidoPara(CarrinhoDeCompras carrinho);
}
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
interface ServiçoDePedidos {
public Pedido criaPedidoPara(CarrinhoDeCompras carrinho, Cliente cliente);
}
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
Um serviço poderia usar isso trnaquilamente. O Cliente poderia usar tb assim
class Cliente {
public List<Pedido> getPedidos(){
return repositorioDePedidos.encontraTodosPedidosPara(this);
}
}
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":
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... )