bonfarj:
sergiotaborda:
Não. Em O não ha "relacionamentos", ha objetos contendo objetos. Isso é um grafo.
(...)
2) A relação entre cliente e pedido não forma um grafo fixo.
Eu realmente fiquei confuso com essa concepção de grafo, não entendi. Imagine que uma classe Pedido possui um atributo Cliente. Isso não pode ser visto como um relacionamento entre as duas classes? Seguindo o que você falou, Cliente pertence ou não ao grafo de Pedido? Se você tiver um link falando sobre grafos nesse contexto eu gostaria de ver, não consegui entender bem.
Pedido contém um atributo do tipo Cliente. Sim. Cliente pertence ao grafo de Pedido e eu faço pedido.getCliente().
O cliente do pedido reponde a "Quem fez o pedido?"
Mas se eu quiser responder a "Quais pedidos o cliente fez?" ai eu uso cliente.getPedidos().
Com estas duas coias eu posso responder a "Que pedidos o cliente que fez este pedido, fex?" apenas com pedido.getCliente().getPedidos().
Isto é uma regra de dominio.
O facto de pedido ter um atributo ter um cliente sim pode ser encarado como um relacionamento entre as duas entidades, mas esse relacionamento é "virtual" ou seja, não existe um objeto Relacionamento que tenha um referencia a cada um. (Poderia haver, mas normalmente não ha). O que ha é uma Referencia de pedido a cliente , mas não de cliente a pedidos. Quando executa Cliente.getpedidos() vc está executando uma regra de negocio que é muito mais complexa que pedido.getCliente(). cliente.getPedido() implica num raciocinio "procura os pedidos onde o cliente é this"
Em codigo :
class Pedido {
Cliente cliente; // attributo. Cliente pertence ao grafo fixo de Pedido
}
class Cliente {
// não ha nenhuma referencia ao Set<Pedido>
public Set<Pedido> getPedidos(){
return PedidoRepository.findByClient(this);
}
}
Embora do lado de fora pareça que Set<Pedidos> existe dentro de cliente, ele não existe de fato. Isso é a vantagem de encasulação.
O que tudo isto interessa?
Quando vc salva o pedido , ha um campo na tabela Pedido que diz respeito ao cliente. Logo o sistema tem que averiguar se o cliente está tb salvo. Se não, salva-o ( ou salva-o logo por default e pronto)
Mas quando o sistema salva o cliente ele não salva a coleção de pedidos. Porque ele não salava? porque não ha nenhum atributo desse tipo em cliente.
Então getPedidos() parece igual a getCliente(), mas não são. Mas o objetivo do DDD é exatamente que pareçam, mesmo que internamente não sejam.
Agora que eu não entendi mesmo. Necessidade de andar com uma lista? Mas isso não está relacionado a forma como você implementa? Também não entendi o porquê de Cliente não conter uma coleção de pedidos, porque o que você descreveu, para mim, indica claramente que existe um relacionamento bidirecional entre as duas classes.
!
Se o cliente contivesse um lista de pedidos cada vez que vc salva o cliente salvaria os pedidos e cada vez que retorna um cliente, retorna todos os pedidos tb. Entenda que isso cria um cliclo vicioso. Salvar o pedido salva o cliente que salva o pedido, que salva o cliente ... Claro que a sua ferramente de persistencia pode evitar isso, mas o ponto aqui é que Pedido não pertence ao grafo de cliente. Pedido não especifica o cliente. Mas cliente especifica o pedido. Essa é a diferença.
E não, ninguém anda com uma lista. Sim, depende de como implementa. Mas se vc implementar diferente vai ter muita dor de cabeça por causa do paradoxo que falei antes.
Em termos de banco de modelo E-R existe um relacionamento bidirecional, mas em termos de DDD e OO não. Isso porque não é a mesma coisa vc obter pedidos a partir de um cliente e o cliente ter uma referencia a esses pedidos. E em OO o que conta são as referencias e não os relacionamentos.
Pense assim : vc poderia executar PedidosRepository.findByCliente(Cliente c) sempre que precisasse em qq ponto da aplicação. Mas isso é uma falha de encasulamento. Isso é equivalente a usar o objeto cliente como um DTO e isso é contra a ideia do DDD. É mais claro , e simples , que seja cliente.getPedidos().
Espero ter esclarecido.