forum icon indicating copy to clipboard operation
forum copied to clipboard

DDD Abordagem tática - Agregados e Repositórios

Open ddnascimento opened this issue 4 years ago • 3 comments

Olá Devs!

Estou estudando sobre DDD e tentando aplicar seus conceitos utilizando nosso amado Laravel. Entretanto, minha pergunta não é sobre framework especificamente mas sobre a correta abordagem no que diz respeito a parte tática do DDD. Me desculpem se o assunto estiver muito fora do que o fórum discute, mas serei grato pela atenção.

Problemática

Vamos lá! Supondo que eu tenha um agregado Client e este possui uma lista de desejos. Cada item da lista corresponde a um Product.

Dito isso, se eu precisar remover um item da lista, recorro a entidade Client. Algo como:

$client->removeFromWishList(Product $product))

O método removeFromWishList(...) contém algumas regras que precisam estar em conformidade para remoção. Se tudo estiver ok, o produto será removido da lista de desejos contida no objeto Client.

Porém essa remoção é só em memória. Então utilizo uma Application Service, que tem acesso ao repositório que irá tratar da remoção. A pergunta é: O que o repositório que contém o método de remoção deverá receber como argumento?


Abordagem

  1. Caso receba como argumento o objeto Client: Como saberei qual produto terei de remover uma vez que tal produto não está mais na lista de desejos? Ex.:

    $clientRepository->removeFromWishList(Client $client)

  2. Caso receba como argumento o objeto Product ou o id do produto que será removido: Dessa forma, eu entendo que estaria removendo qualquer produto sem passar pelo método removeFromWishList(...) ignorando as regras que garantem a remoção citada anteriormente.

    Ex.:

    $clientRepository->removeFromWishList(Product $product)

    Ou:

    $clientRepository->removeFromWishList($productId)

Não ficou claro para mim qual das abordagens citadas (ou nenhuma delas...) seria a ideal.

Da mesma forma não entendo se terei de carregar todos os produtos da lista de desejos para o objeto Client sempre que eu quiser remover um produto da lista (passando pelas regras que garantem a remoção).

Desde já agradeço pela atenção.

ddnascimento avatar Dec 20 '20 01:12 ddnascimento

Posso dizer como eu implementaria.

Eu passaria como parâmetro para o $$clientRepository->removeFromWishList o Client e o Product.

$clientRepository->removeFromWishList(Client $client, Product $product)

Isso resolve seu problema aqui:

  1. Caso receba como argumento o objeto Client: Como saberei qual produto terei de remover uma vez que tal produto não está mais na lista de desejos? Ex.:

Me avisa se isso estiver errado de alguma forma.

esron avatar Dec 21 '20 23:12 esron

@esron Obrigado pela atenção. Eu entendo que dessa forma proposta não garante que o programador futuramente utilize esse método fornecendo ...removeFromWishList(Client $client, Product $product) ao invés de passar pela regra de validação de remoção contido no modelo $client->removeFromWishList(Product $product)) sabe... Mas também não sei se o DDD aborda tal situação com essa profundidade de segurança ou não compreendi a mecânica das coisas... rs.

Grato por compartilhar sua visão!

ddnascimento avatar Dec 22 '20 01:12 ddnascimento

Tudo bem, @ddnascimento ? Na verdade são algumas decisões arquiteturais que você precisa tomar. Considerando o cenário descrito, você em algum momento precisa criar a relação entre Client e Product. Aí vai de encontro com a sugestão do @esron . Uma alternativa é você criar um domínio para representar uma lista de desejos. Dessa forma, você poderia compor a lista de desejos no Client aonde toda lista teria 1 client e N products. Por exemplo, poderia fazer algo assim:

$whilist = new Wishlist($client);
$wishlist->remove($product);

Ou, o que seria mais próximo do que você quer:

$client->wishlist->remove($product);

Espero ter ajudado de alguma forma. No fim das contas, tu precisará testar as possibilidades pra ver o que vai se encaixar melhor. Abs \0

josemoraes avatar May 21 '21 23:05 josemoraes