DDD - Apakah repositori root agregat menangani penghematan agregat?

27

Saya menggunakan pendekatan seperti-DDD untuk modul greenfield dari aplikasi yang ada; itu bukan 100% DDD karena arsitektur tapi saya mencoba menggunakan beberapa konsep DDD. Saya memiliki konteks terbatas (saya pikir itu istilah yang tepat - saya masih belajar tentang DDD) yang terdiri dari dua Entitas: Conversationdan Message. Percakapan adalah root, karena Pesan tidak ada tanpa percakapan, dan semua pesan dalam sistem adalah bagian dari percakapan.

Saya memiliki ConversationRepositorykelas (walaupun sebenarnya lebih mirip Gateway, saya menggunakan istilah "Repositori") yang menemukan Percakapan dalam database; ketika menemukan Percakapan, ia juga membuat (melalui Pabrik) daftar pesan untuk Percakapan itu (diekspos sebagai properti). Ini tampaknya menjadi cara yang benar dalam menangani berbagai hal karena tampaknya tidak ada kebutuhan untuk kelas penuh MessageRepositorykarena hanya ada ketika Percakapan diambil.

Namun, ketika datang untuk menyimpan Pesan, apakah ini tanggung jawab dari ConversationRepository, karena ini adalah akar agregat dari Pesan? Apa yang saya maksud adalah, haruskah saya memiliki metode tentang ConversationRepository yang disebut, katakanlah, AddMessageyang mengambil pesan sebagai parameternya dan menyimpannya ke database? Atau haruskah saya memiliki repositori terpisah untuk menemukan / menyimpan Pesan? Hal yang logis tampaknya menjadi satu repositori per Entitas, tetapi saya juga pernah mendengar "Satu repositori per Konteks".

Wayne Molina
sumber

Jawaban:

25

The buku biru pasti patut dibaca jika Anda ingin mendapatkan keluar terbaik dari pendekatan DDD. Pola-pola DDD tidak sepele dan mempelajari esensi dari masing-masing pola itu akan membantu Anda merenungkan kapan harus menggunakan pola mana, cara membagi aplikasi Anda menjadi berlapis-lapis, cara mendefinisikan Agregat Anda, dan sebagainya.

Grup 2 entitas yang Anda sebutkan bukan Konteks Terbatas - mungkin Agregat. Setiap Agregat memiliki Agregat Root, Entitas yang berfungsi sebagai titik masuk tunggal ke Agregat untuk semua objek lainnya. Jadi tidak ada hubungan langsung antara Entitas dan Entitas lain di Agregat lain yang bukan Root Agregat.

Repositori diperlukan untuk mendapatkan Entitas yang tidak mudah diperoleh dengan melintasi objek lain. Repositori biasanya berisi Root Agregat, tetapi bisa juga ada Repositori Entitas reguler.

Dalam contoh Anda, Percakapan tampaknya menjadi Root Agregat. Mungkin Percakapan adalah titik awal aplikasi Anda, atau mungkin Anda ingin menanyakannya dengan kriteria terperinci sehingga tidak dapat diakses secara memuaskan melalui traversal sederhana objek lain. Dalam kasus seperti itu, Anda dapat membuat Repositori untuk mereka yang akan memberikan kode klien ilusi satu set Percakapan di dalam memori untuk meminta, menambah atau menghapus dari secara langsung. Pesan di sisi lain mudah diperoleh dengan melintasi suatu Percakapan, dan Anda mungkin tidak ingin mendapatkannya sesuai dengan kriteria terperinci, hanya semua Pesan Percakapan sekaligus, sehingga mereka mungkin tidak memerlukan Repositori.

ConversationRepository akan memainkan peran dalam mempertahankan Pesan, tetapi tidak seperti peran langsung seperti yang Anda sebutkan. Jadi, tidak ada AddMessage () di ConversationRepository (metode itu lebih baik milik Conversation itu sendiri) tetapi sebaliknya, setiap kali Repository akan bertahan dalam suatu Conversation, ada baiknya untuk tetap melanjutkan Pesan-pesannya pada saat yang sama, baik secara transparan jika Anda menggunakan kerangka kerja ORM seperti (N) Hibernate, menggunakan ad hoc SQL jika Anda memilihnya, dll.

guillaume31
sumber
1
Jika root agregat, seperti Conversation, memiliki banyak jenis entitas yang berbeda di dalamnya, seperti Message, Thingies, dan Wingies, maka ketika Anda menyimpan percakapan, misal ConversationRepo.save (percakapan), bagaimana Anda tahu entitas mana di dalamnya yang perlu untuk diselamatkan? Dalam contoh poster di atas, hanya entitas pesan yang perlu disimpan. Apakah Anda menelusuri semua koleksi yang memungkinkan dalam akar agregat untuk menemukan entitas tanpa id?
chris-richards
3

Anda bisa membuat ConversationService dan menyuntikkan IConversationRepository dan IMessageRepository dalam konstruktornya. Gunakan repositori untuk operasi CRUD sederhana, dan layanan untuk yang lainnya (caching, hemat logika, dll.)

šljaker
sumber
1
tidak menyimpan logika CRUD?
Timothy Groote