Apakah Objek Domain dalam Desain Berbasis Domain hanya seharusnya hanya untuk penulisan?

13

Saya telah membaca tentang Desain Berbasis Domain selama hampir dua tahun dan telah dengan hati-hati memperkenalkan beberapa konsep dalam pekerjaan sehari-hari saya atau setidaknya membuat rencana untuk bagaimana hal-hal yang saya lakukan secara teratur dapat dilakukan dalam Desain Berbasis Domain.

Salah satu kesimpulan yang saya mulai datang terutama dalam menanggapi membaca lebih lanjut tentang Event Sourcing dan Segregasi Command Query Responsibility (CQRS) yang mungkin objek domain dimaksudkan untuk digunakan hanya untuk tujuan menulis. Untuk lebih jelas, tampaknya apa yang orang secara halus menyarankan dalam banyak dokumentasi yang saya baca bahwa objek domain bertanggung jawab untuk melakukan operasi / perhitungan, pengesahan domain sentris, dan kemudian ada terutama untuk menyediakan jalan menuju kegigihan melalui infrastruktur yang disediakan dalam implementasi Repositori. Walaupun saya sangat menyukai kenyataan bahwa ini dapat menyederhanakan model domain karena hal ini mengurangi tanggung jawab untuk mengekspos status.

Jika memang benar bahwa objek domain terutama untuk digunakan sebagai objek menulis saja maka itu menimbulkan beberapa pertanyaan bagi saya bahwa saya berharap seseorang dapat menjawab.

  1. Bagaimana seseorang melakukan tes unit pada objek yang memiliki setter, atau metode yang mengubah keadaan objek tetapi yang tidak memberikan antarmuka publik ke luar untuk membaca status dari seperti properti getter di C #? Apakah saya tetap bisa mengekspos keadaan hanya untuk tujuan membuat objek itu dapat diuji?
  2. Bagaimana seseorang menunjukkan kepada pengguna hasil perhitungan atau operasi yang dilakukan dalam domain tanpa harus bertahan dan kemudian menarik hasilnya dari toko tetap di luar konteks domain? Apakah saya tetap bisa mengekspos negara hanya untuk tujuan menunjukkan hasil.

Apakah aturan praktis bahwa satu-satunya pengambil properti (dapatkan pengakses) haruslah yang juga dapat ditulis dalam domain? Atau mengatakan secara berbeda apakah properti hanya baca harus menjadi satu-satunya hal yang harus dihindari karena mereka hanya ada untuk tujuan membaca dan dengan demikian tidak memainkan peran yang diperlukan dalam model domain yang sebenarnya?

Bahan terkait:

  1. TDD, DDD dan Enkapsulasi
jpierson
sumber

Jawaban:

9

Tidak yakin bahwa ada jawaban 'satu jalan sejati' untuk pendekatan desain yang, agar adil, masih berkembang. Pertama, DDD dan CQRS bukan hal yang sama meskipun orang-orang CQRS tampaknya berasal dari titik awal yang dipengaruhi oleh DDD.

Ada banyak hal yang terjadi dalam pola pikir DDD dan sebagian besar berkaitan dengan batasan masalah, komunikasi di antara para pemangku kepentingan, dan interaksi antara sistem, belum tentu implementasi spesifik dalam kode, jadi saya tidak berpikir terlalu sulit- inti adalah kebajikan.

Anda mungkin melihat beberapa perdebatan tentang apakah dan bagaimana objek domain harus dapat diubah, dan apa fungsi objek domain yang berfungsi dalam suatu sistem secara keseluruhan. CQRS membagi sistem menjadi jalur baca dan tulis, jadi masuk akal untuk menyimpulkan bahwa Anda sebenarnya tidak perlu akses baca ketika Anda berada di jalur tulis. Membaca kemudian menjadi sesuatu yang Anda lakukan terhadap peristiwa yang diangkat oleh beberapa objek domain dan dikonsumsi (ditangani) oleh orang lain. Jika Anda kembali sedikit dalam sejarah CQRS, Anda akan menemukan argumen bahwa objek domain tidak boleh memiliki setter, hanya getter dan metode 'penangan' tunggal. Logikanya di sini adalah bahwa hanya peristiwa mengkonsumsi harus menghasilkan perubahan negara, dan perubahan itu sepenuhnya ditangani secara internal oleh objek domain.

Anda menunjukkan hasil perubahan dengan memperlakukannya sebagai artefak perubahan yang terpisah, menempatkannya dalam struktur persisten yang terpisah (mis., Tabel) dan membacanya seolah-olah Anda baru saja membaca laporan tentang keadaan sistem saat ini dan historis sistem . Misalnya, Anda dapat menggunakan acara dengan mengekstraksi data yang Anda butuhkan untuk membaca dan menyimpannya ke tabel database yang memetakan secara dekat ke satu tampilan (misalnya layar) dari sistem Anda.

Jika Anda bereksperimen dengan gaya ini, sadarilah bahwa programmer lain mungkin tidak akan terbiasa dengan pendekatan ini, dan bahwa ada beberapa skenario (tapi menarik) yang relatif sedikit di mana itu dibenarkan sebagai pendekatan desain.

Untuk pengujian unit, ada beberapa pendekatan yang mungkin cocok untuk Anda. Yang pertama, dan yang paling alami, adalah untuk memverifikasi peristiwa yang Anda harapkan untuk dibangkitkan oleh objek domain Anda sudah benar. Objek domain mungkin memunculkan perubahan umum yang menyimpan informasi tentang perubahan tersebut. Anda dapat memverifikasi itu. Anda dapat memverifikasi fakta bahwa acara tersebut dimunculkan sama sekali, dan bahwa acara lain tidak diangkat.

Pendekatan lain adalah menggunakan Test Spies yang mengekspos atribut yang dapat dibaca pada objek domain Anda sehingga Anda dapat memverifikasi perubahan status. Misalnya, Anda dapat mewarisi dari objek domain Anda, menambahkan beberapa pengakses untuk membaca keadaan yang akan dienkapsulasi dan memverifikasi bahwa itu benar.

Sekali lagi, Anda bingung karena pendekatan ini membingungkan. Jika Anda ingin mengadopsi beberapa ide bagus ke dalam pemrograman Anda, ambillah bit juicy terlebih dahulu. Batas-batas DDD dan membuat peran eksplisit adalah perubahan cara berpikir Anda tentang berkomunikasi dengan kode Anda. CQRS setidaknya menunjukkan bahwa membaca data dan menulis data adalah operasi yang dapat dipisahkan. Wawasan itu membuat Anda berpikir dengan sangat jelas tentang apa peran data yang Anda butuhkan untuk disajikan adalah, berapa banyak yang benar-benar Anda butuhkan, siapa yang mengkonsumsinya, seberapa segar hal itu diperlukan, dll ... Anda tidak memerlukan implementasi sumber acara penuh sesak nafas untuk mengadopsi enkapsulasi yang lebih baik dalam pengkodean Anda. Anda bisa mulai dengan hanya berfokus pada operasi atom dalam objek Anda, "Katakan, Jangan Tanyakan" pendekatan untuk desain antarmuka objek,

pfries
sumber
1
+1 untuk memulai dengan bit jucy. Selain itu: menggigit CQS saja (melewatkan bagian 'acara' untuk saat ini) bisa menjadi tempat yang baik untuk memulai.
cottsak
1

Apakah Objek Domain dalam Desain Berbasis Domain hanya seharusnya hanya untuk penulisan?

Tidak. CQRS dapat digunakan bersama DDD.

NimChimpsky
sumber
Tetapi apakah Query bagian dari CQRS semua tentang permintaan data yang digunakan oleh model domain untuk menulis perubahan pada model atau dapatkah itu digunakan untuk menanyakan data untuk lapisan aplikasi yang mungkin mengatakan menunjukkan nilai kepada pengguna? Saya mendengar dari beberapa orang bahwa DDD adalah tentang mengoordinasikan perubahan dan tidak boleh digunakan untuk membaca dari tujuan lain selain mengoordinasikan perubahan ke objek lain dalam model domain. Keputusan satu arah atau yang lain akan berarti desain model yang sangat berbeda melihat bahwa data yang terbuka pada objek domain akan bervariasi terbatas jika hanya dikonsumsi dalam domain.
jpierson
0

Tes unit model domain Anda harus memeriksa bahwa untuk setiap perintah yang dijalankan peristiwa domain yang benar dimunculkan. Perintah domain Anda dan acara yang diambil dapat diinterogasi untuk kondisi.

Anda juga dapat mengesampingkan ToString()perintah dan acara domain Anda untuk menyediakan pelaporan keadaan otomatis yang dapat dibaca manusia.

Untuk menjawab pertanyaan kedua Anda, untuk menampilkan hasil perintah, Anda harus mengatur agar peristiwa domain 'dipublikasikan' ke model-baca Anda.

Ed James
sumber
Bisakah Anda menguraikan sedikit tentang apakah ini masih berlaku ketika Anda tidak menggunakan event-sourcing?
jpierson
1
Tanpa sumber acara mungkin saran saya tidak akan berfungsi; Saya tidak tahu cara kode Anda. Untuk objek domain yang idealnya tidak mengekspos properti apa pun, mungkin Anda dapat secara eksplisit mengimplementasikan antarmuka uji yang mengekspos properti yang ingin Anda uji. Hanya kode pengujian Anda yang akan 'tahu' untuk melemparkan objek domain tersebut ke antarmuka uji.
Ed James
Terima kasih untuk saran itu. Saya merasa agak gelisah tentang gagasan memodifikasi kelas domain saya khusus untuk testabilitas, tetapi saya kira ini mungkin salah satu dari area abu-abu yang masih dalam Domain Driven Design jika Anda ingin itu bisa diuji. Pikiran lain adalah bahwa jika seseorang mengekspos stabilitas dan testabilitas melalui antarmuka yang sama maka setidaknya Anda hanya memperkenalkan satu ketergantungan infrastruktur daripada dua. Apa yang orang lain pikirkan tentang itu?
jpierson