Skenario:
Pelanggan memesan, kemudian, setelah menerima produk, memberikan umpan balik pada proses pemesanan.
Asumsikan akar agregat berikut:
- Pelanggan
- Memesan
- Umpan balik
Berikut adalah aturan bisnisnya:
- Seorang pelanggan hanya dapat memberikan umpan balik atas pesanan mereka sendiri, bukan milik orang lain.
Pelanggan hanya dapat memberikan umpan balik jika pesanan telah dibayar.
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; } }
Sekarang, anggap bisnis menginginkan aturan baru:
Pelanggan hanya dapat memberikan umpan balik jika
Supplier
barang pesanan masih beroperasi.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; } }
Saya telah menempatkan implementasi dari dua aturan pertama dalam Feedback
agregat itu sendiri. Saya merasa nyaman melakukan ini, terutama mengingat bahwa
Feedback
agregat merujuk semua agregat lainnya berdasarkan identitas. Misalnya, sifat-sifat Feedback
komponen menunjukkan bahwa ia mengetahui
keberadaan agregat lain, jadi saya merasa nyaman mengetahui tentang status read only dari agregat ini juga.
Namun, berdasarkan sifat itu, yang Feedback
agregat tidak memiliki pengetahuan tentang keberadaan dari
Supplier
agregat, sehingga seharusnya ia memiliki pengetahuan tentang membaca satunya negara dari agregat ini?
Solusi alternatif untuk menerapkan aturan 3 adalah dengan memindahkan logika ini ke yang sesuai CommandHandler
. Namun, ini terasa seperti memindahkan logika domain dari "pusat" arsitektur berbasis bawang saya.
Supplier
status operasi agregat tidak akan ditanyai melalui Order
repositori; Supplier
dan Order
dua agregat terpisah. Kedua, ada pertanyaan di milis DDD / CQRS tentang meneruskan akar agregat dan repositori ke metode akar agregat lainnya (termasuk konstruktor). Ada berbagai pendapat, tetapi Greg Young menyebutkan bahwa melewati akar agregat sebagai parameter adalah umum, sementara orang lain mengatakan bahwa repositori lebih erat terkait dengan infrastruktur daripada domain. Misalnya, repositori "abstrak dalam koleksi memori" dan tidak memiliki logika.
Customer
kaleng hanya memberikan umpan balik pada salah satu pesanan mereka sendiri ( $order->customerId() == $customer->customerId()
), kami juga harus membandingkan ID pemasok ( $order->supplierId() == $supplier->supplierId()
). Aturan pertama melindungi pengguna yang memberikan nilai yang salah. Aturan kedua menjaga terhadap programmer yang memasok nilai yang salah. Namun demikian, pemeriksaan apakah pemasok beroperasi harus dalam Feedback
entitas, atau dalam pengendali perintah. Dimana pertanyaannya?