Evans memperkenalkan dalam bukunya "Domain Driven Design" di Bab 6 "Agregat" konsep Agregat. Dia lebih jauh mendefinisikan aturan untuk menerjemahkan konsep itu ke dalam implementasi (Evans 2009, hlm. 128-129):
Root ENTITY dapat menyerahkan referensi ke ENTITAS internal ke objek lain, tetapi objek tersebut dapat menggunakannya hanya sementara, dan mereka mungkin tidak berpegang pada referensi.
Setelah menguraikan aturan lain, ia merangkumnya ke dalam paragraf ini:
Cluster Entitas dan Nilai Objek menjadi Agregat dan menentukan batas-batas di sekitar masing-masing. Pilih satu Entitas untuk menjadi root dari setiap Agregat, dan kontrol semua akses ke objek di dalam batas melalui root. Izinkan objek eksternal untuk menyimpan referensi ke root saja. Referensi sementara untuk anggota internal dapat dikeluarkan untuk digunakan dalam satu operasi saja. Karena root mengontrol akses, ia tidak bisa dibohongi oleh perubahan pada internal. Pengaturan ini membuatnya praktis untuk menegakkan semua invarian untuk objek dalam Agregat dan untuk Agregat secara keseluruhan dalam setiap perubahan negara.
Jadi apa sebenarnya arti dari penggunaan sementara?
Kolega saya mengerti bahwa hanya root agregat yang memperlihatkan antarmuka publik untuk klien. Klien tidak akan memiliki kesempatan untuk memanggil operasi apa pun pada entitas selain dari akar agregat.
Pemahaman saya tentang kalimat yang dikutip berbeda. Saya mengerti bahwa itu memang secara eksplisit memungkinkan klien memanggil operasi pada entitas internal. Namun hanya setelah mendapatkannya dari root.
Jadi, mari kita ambil contoh konkret:
Misalkan a Cart
terdiri dari banyak Items
. Masing-masing Item
memiliki a Quantity
. Model harus mendukung use case "Tingkatkan jumlah satu Item tertentu". Tidak ada invarian yang bisa dilanggar yang memengaruhi apa pun di luar Item.
Apakah model melanggar aturan yang dikutip di atas, ketika klien dapat melakukan ini dengan menelepon cart.item(itemId).increaseQuantity()
atau haruskah klien hanya diizinkan untuk memanggil cart.increaseItemQuantity(itemId)
? Apa manfaat yang terakhir?
cart.increaseItemQuantity(itemId)
, jika tidak ada alasan lain selain kurang dari pelanggaran Hukum Demeter. Menelepon cart.increaseItemQuantity(itemId)
memungkinkan Anda melakukan hal-hal seperti memperbarui jumlah total keranjang.