Cenário:
Um cliente faz um pedido e, depois de receber o produto, fornece feedback sobre o processo do pedido.
Suponha as seguintes raízes agregadas:
- Cliente
- Ordem
- Comentários
Aqui estão as regras de negócios:
- Um cliente pode apenas fornecer feedback sobre seu próprio pedido, não sobre o de outra pessoa.
Um cliente pode fornecer feedback apenas se o pedido tiver sido pago.
class Feedback { public function __construct($feedbackId, Customer $customer, Order $order, $content) { if ($customer->customerId() != $order->customerId()) { // Error } if (!$order->isPaid()) { // Error } $this->feedbackId = $feedbackId; $this->customerId = $customerId; $this->orderId = $orderId; $this->content = $content; } }
Agora, suponha que a empresa queira uma nova regra:
Um cliente pode fornecer feedback apenas se as
Supplier
mercadorias do pedido ainda estiverem em operação.class Feedback { public function __construct($feedbackId, Customer $customer, Order $order, Supplier $supplier, $content) { if ($customer->customerId() != $order->customerId()) { // Error } if (!$order->isPaid()) { // Error } // NEW RULE HERE if (!$supplier->isOperating()) { // Error } $this->feedbackId = $feedbackId; $this->customerId = $customerId; $this->orderId = $orderId; $this->content = $content; } }
Coloquei a implementação das duas primeiras regras no Feedback
próprio agregado. Sinto-me à vontade para fazer isso, especialmente porque o
Feedback
agregado faz referência a todos os outros agregados por identidade. Por exemplo, as propriedades do Feedback
componente indicam que ele conhece a
existência dos outros agregados, então me sinto confortável em saber também o estado somente leitura desses agregados.
No entanto, com base em suas propriedades, o Feedback
agregado não tem conhecimento da existência do
Supplier
agregado; portanto, ele deve ter conhecimento do estado somente leitura desse agregado?
A solução alternativa para a implementação da regra 3 é mover essa lógica para o apropriado CommandHandler
. No entanto, parece que está afastando a lógica do domínio do "centro" da minha arquitetura baseada em cebola.
Supplier
o estado operacional de um agregado não seria consultado por meio de um Order
repositório; Supplier
e Order
são dois agregados separados. Em segundo lugar, havia uma pergunta na lista de discussão DDD / CQRS sobre a passagem de raízes e repositórios agregados para outros métodos raiz agregados (incluindo o construtor). Havia uma variedade de opiniões, mas Greg Young mencionou que transmitir raízes agregadas como parâmetros é comum, enquanto outra pessoa disse que os repositórios estão mais intimamente relacionados à infraestrutura do que ao domínio. Por exemplo, repositórios "abstraem coleções de memória" e não têm lógica.
Customer
só pode fornecer feedback sobre um de seus próprios pedidos ( $order->customerId() == $customer->customerId()
), também precisamos comparar o ID do fornecedor ( $order->supplierId() == $supplier->supplierId()
). A primeira regra protege contra o usuário que fornece valores incorretos. A segunda regra protege contra o programador que fornece valores incorretos. No entanto, a verificação sobre se o fornecedor está operando deve ser na Feedback
entidade ou no manipulador de comandos. Onde está a questão?