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
Supplierbarang 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
Feedbackagregat merujuk semua agregat lainnya berdasarkan identitas. Misalnya, sifat-sifat Feedbackkomponen 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 Feedbackagregat tidak memiliki pengetahuan tentang keberadaan dari
Supplieragregat, 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.
Supplierstatus operasi agregat tidak akan ditanyai melalui Orderrepositori; Supplierdan Orderdua 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.
Customerkaleng 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 Feedbackentitas, atau dalam pengendali perintah. Dimana pertanyaannya?
