DDD - Apakah model domain anemia merupakan antipattern? Haruskah kita menggunakan model domain kaya? [Tutup]


11

Model domain anemia telah lama dikritik oleh Evans dan Fowler , karena tampaknya bertentangan dengan prinsip-prinsip berorientasi objek, dll. Komunitas DDD jelas selaras dengan pernyataan ini.

Namun, dalam beberapa tahun terakhir telah ada suara-suara yang tidak setuju yang mengklaim itu bukan anti-perpindahan sama sekali dan itu adalah contoh dari mengikuti prinsip-prinsip SOLID.

Saya telah bekerja bertahun-tahun menggunakan Spring Framework. Setiap proyek di setiap perusahaan selalu memiliki lapisan layanan yang berisi logika bisnis, menggunakan repositori yang beroperasi pada model anemia (entitas JPA). Selain itu, sebagian besar sampel, bahkan yang resmi dari Spring guys, memamerkan cara kerja ini.

Pertanyaan saya adalah: apakah model domain anemia masih dianggap sebagai antipattern? Apakah kita semua melakukan hal-hal (mengenai DDD) yang salah? Tidakkah Anda berpikir bahwa memiliki model Rich Domain melanggar prinsip SOLID?


2
"Apakah model domain anemia masih dianggap sebagai antipattern? " Oleh sebagian orang, ya. Oleh orang lain, termasuk saya sendiri, lihat itu sebagai cara yang paling disukai untuk menulis kode sebagian besar waktu, tetapi jika RDM cocok untuk Anda, gunakan itu. Jadi voting untuk menutup ini murni berdasarkan opini.
David Arno

1
Ini akan menjadi pertanyaan fantastis untuk forum diskusi / debat; tetapi saat ini tidak ada jawaban yang resmi. Kami lebih suka pertanyaan yang bisa dijawab, bukan hanya dibahas.
VoiceOfUnreason

Jawaban:


9

ADM adalah pola yang baik untuk solusi layanan terdistribusi seperti layanan-mikro. Ini cocok dengan banyak kasus bisnis berbasis web saat ini.

Pertimbangkan jika kita memiliki objek Domain Pesanan. Dengan pendekatan OOP kami akan menambahkan Order.Purchase () Order.Cancel () dll. Ini akan bekerja dengan baik di aplikasi desktop, di mana kami menyimpan pesanan di memori dan melakukan beberapa hal pada contoh yang sama.

Tetapi jika kita memiliki sistem terdistribusi, dengan program yang hanya untuk satu hal, yaitu mengakses daftar pesanan dan membeli masing-masing secara bergantian, atau mendapatkan daftar pesanan dan membatalkan masing-masing secara bergantian kemudian memiliki kedua Metode pada objek yang sama membuat tidak ada merasakan. Kami harus memiliki dua Domain atau Konteks Terbatas:

PurchaseSystemOrder.Purchase()

dan

CancelSystemOrder.Cancel();

Satu-satunya benda yang akan dibagikan benda-benda ini adalah struktur data properti.

Ketika Anda menambahkan lebih banyak dan lebih banyak layanan microser, Anda berakhir dengan puluhan jenis Order. Tidak lagi masuk akal untuk berbicara tentang sebuah Orde sebagai objek Domain, meskipun yang tatanan konseptual yang sama yang sedang diproses oleh semua sistem ini.

Jauh lebih masuk akal untuk memiliki model Anemik, Pesanan, yang hanya merangkum data saja dan mengubah nama layanan Anda sesuai:

PurchaseService.Purchase(Order order)

Sekarang kita dapat membicarakan Order lagi dan kita dapat menambahkan layanan baru apa pun yang kita pikirkan untuk diproses, tanpa memengaruhi layanan lain yang saat ini digunakan.

Fowler and Co berasal dari latar belakang sistem monolith, di dunia mereka pendekatan ADM akan berarti aplikasi tunggal dengan semua layanan terpisah ini dipakai dalam memori dan OrderDTO diedarkan dan dimutasi. Ini akan jauh lebih buruk daripada menempatkan metode pada model Orde kaya.

Tetapi dalam sistem terdistribusi, ada banyak program, masing-masing hanya membutuhkan metode Pesanan tunggal dan menjalankannya pada beberapa pesanan, memuat masing-masing, menjalankan metode dan kemudian membuangnya. Hanya membutuhkan Layanan tunggal dan aliran objek data.

Mengisi model kaya sepenuhnya, khawatir tentang persyaratan dan dependensi dari semua Metode hanya untuk memanggil satu dan kemudian membuang objek segera adalah sia-sia.

Ditambah perubahan ke salah satu metode akan memerlukan memperbarui semua komponen yang didistribusikan karena mereka semua bergantung pada Model Kaya untuk logika mereka.

Saya tidak punya ruang di basis kode saya untuk hal-hal yang tidak mereka butuhkan


4
Saya downvoted karena saya pikir DDD sangat cocok untuk layanan microser justru karena konsep konteks terbatas. Saya pikir masalah dengan jawaban Anda adalah bahwa Anda memesan konsep dan kelas akan sama di setiap layanan mikro tapi saya pikir itu tidak perlu atau akurat.
RibaldEddie

Saya tidak setuju, ADM bisa menjadi DDD jika Anda memanggil PurchaseService Anda CashRegister dan menjadikannya bagian dari bahasa domain Anda
Ewan

bisakah kamu menguraikan? Saya selalu berpikir bahwa YMMV ketika ADM dan DDD berada dalam basis kode SOLID J2EE atau .NET C # MVC EF.
RibaldEddie

Yang saya maksud adalah bahwa konteks terikat Order, PurchaseSystemOrder.Purchase () akan menjadi kode yang hampir identik dengan CashRegister.Purchase (Order order) hanya merupakan perubahan penamaan dalam bahasa domain Anda. Model domain kaya berarti memiliki metode Pembelian dan Batalkan pada kelas yang sama.
Ewan

1
@RibaldEddie, Di tengah ketebalan buku "javaScript, bagian yang baik", saya menawarkan gambar ini sebagai argumen (tidak sepenuhnya serius) terhadap penggunaan DDD untuk mengimplementasikan layanan microser;)
David Arno

3

SOLID dan DDD saling ortogonal satu sama lain, artinya mereka benar-benar pergi ke arah yang berbeda satu sama lain. Anda seharusnya tidak mengatakan bahwa yang satu digunakan untuk mengesampingkan yang lain, karena mereka bisa dan mungkin harus ada bersama dalam basis kode yang sama.

Model domain anemia hanya menjadi anti-pola setelah domain masalah Anda memiliki banyak perilaku dan Anda memiliki ratusan metode layanan dengan banyak logika atau ketergantungan yang disalin-salin di mana metode lapisan layanan harus memanggil metode lapisan layanan lainnya untuk menyelesaikan sesuatu.

DDD adalah paradigma yang sangat baik untuk layanan mikro karena konsep konteks terbatas .

Waspadai godaan untuk melihat kode infrastruktur sebagai bagian dari domain Anda. Kode infrastruktur adalah segala sesuatu yang tidak Anda tulis sendiri atau apa pun yang digabungkan ke kerangka kerja atau pustaka yang berinteraksi dengan sistem pihak ketiga. Koneksi basis data, mailer SMTP, perpustakaan ORM, waktu menjalankan server aplikasi, semua itu adalah infrastruktur dan Anda tidak boleh memasukkan atau bergantung padanya di domain Anda jika Anda bisa menghindarinya.

Prinsip SOLID adalah seperangkat konsep OOP tujuan umum yang dapat Anda gunakan untuk membuat kode OOP yang lebih baik. Anda dapat menulis basis kode DDD yang baik dengan menggunakannya.


Mengenai pemisahan kode infrastruktur dari domain. Sejauh ini saya telah mempertimbangkan Entitas JPA sebagai domain saya, memiliki lapisan aplikasi berikut: controller -> service -> repository -> domain (Entitas JPA). Apa yang akan menjadi cara yang tepat (atau salah satu yang tepat) untuk memodelkannya sesuai dengan poin Anda? Sesuatu seperti: controller -> model kaya -> x? Bagaimana dan di mana saya akan berurusan dengan transaksionalitas? Dan bagaimana dengan Pemetaan JPA? Tidakkah kita harus menduplikasi model kaya kita dengan entitas JPA yang terpisah?
codependent

Entitas JPA adalah objek Java lama biasa. Pemetaan adalah bagian dari infrastruktur tetapi kelas itu sendiri tidak harus demikian. Jika Anda memilih untuk memperlakukannya sebagai bagian dari infrastruktur maka Anda harus menganggapnya sebagai objek transfer data yang digunakan di Pabrik atau Gudang untuk membuat Entitas domain.
RibaldEddie

1

Domain yang kaya bagus jika dilakukan dengan baik. Mimpi buruk saat tidak. Domain anemia selalu buruk. Tapi itu jenis nyaman yang akrab buruk.

Jika Anda hanya menginginkan domain anemik, Anda memilih bahasa yang salah saat memilih bahasa tujuan umum. Bahasa generasi ke-4 berspesialisasi dalam penggunaan khusus. Jika anemia cukup baik menggunakan mereka akan membuat hidup Anda lebih mudah.

Banyak kerangka kerja menyusup ke ruang bahasa sampai Anda tidak dapat mengiklankan pekerjaan sebagai pekerjaan java lagi. Ini pekerjaan Java / Spring. Apa yang mereka lakukan, selain membuat Anda bergantung pada mereka, adalah mengubah bahasa tujuan umum menjadi bentuk bajingan dari bahasa generasi ke-4.

Apakah itu praktik terbaik atau anti-pola? Nah bos Anda kebanyakan hanya peduli apakah Anda dapat mempekerjakan orang untuk bekerja pada basis kode. Jadi, jika kita harus berpura-pura menggunakan bahasa tujuan umum untuk mempekerjakan orang, kita akan melakukannya.

Jika Anda setuju dengan itu maka baik-baik saja. Anda tentu bukan satu-satunya.

Tapi jangan bilang begitulah seharusnya. Jangan bilang itu melakukan apa pun untuk saya lebih dari itu. Saya tahu bagaimana hidup tanpa itu. Saya tahu cara mendorongnya sehingga hanya beberapa hal yang bergantung padanya. Jika Anda meminta saya untuk menyerah dan membiarkannya mengambil alih segalanya hanya karena berjuang itu sulit maka ya saya pikir itu buruk.

Saya tidak punya ruang di basis kode untuk hal-hal yang tidak perlu.

Adapun SOLID dan prinsip-prinsip desain lainnya saya sebagian besar dapat mengikuti mereka bahkan dalam domain anemia. Tidak mengikutinya menyebabkan masalah yang berbeda.


Saya menghargai jawaban Anda dan sangat setuju bahwa beberapa kerangka kerja seperti Spring atau JPA-Hibernate telah menaklukkan lanskap Java. Namun tidak dapat dipungkiri bahwa mereka telah memberikan banyak praktik yang baik dan penyederhanaan yang tidak ditangani oleh Java (JEE) atau salah. Saya sangat antusias dengan DDD dan ingin memahami semua prinsip yang mereka sampaikan. pengalaman, apa platform / bahasa / kerangka kerja terbaik untuk bekerja dengan aplikasi DDD murni (dengan Rich Domain Models)? Ada sampel Github yang bagus yang Anda tahu? Seperti yang Anda katakan saya ingin melakukan sesuatu dengan baik, tidak sesuai dengan praktik buruk.
codependent

Kami tidak melakukan rekomendasi sumber daya di sini. Tapi saya percaya lapisan infrastruktur yang tepat yang berhubungan dengan kerangka kerja berarti Anda dapat menggunakan jenis apa pun yang Anda suka. Perlakukan mereka seperti perpustakaan. Jauhkan pengetahuan mereka dari domain. Juga, jangan mengandalkan sihir. Tahan keinginan untuk menggunakan hal-hal yang tidak bisa Anda buat sendiri. Karena suatu hari Anda mungkin perlu.
candied_orange

Kembali ke titik semula. Bagaimana dengan prinsip-prinsip SOLID? Model domain yang kaya memikul banyak tanggung jawab, ketekunan (JPA), logika bisnis (harus berurusan dengan transaksionalitas), dan lain-lain. Model anemia hanya peduli pada ketekunan setelah memisahkan layanan yang berurusan dengan logika bisnis. Kedengarannya juga lebih mudah untuk diuji. Apa yang salah tentang itu?
codependent

Yang utama adalah Anda mulai membuat pilihan desain berdasarkan kebutuhan sistem daripada kebutuhan semantik. Ini halus, mudah diabaikan, biaya tidak jelas dan sulit untuk dibenarkan mengoreksi. Singkatnya itu seperti berdebat bahwa saluran listrik harus dikubur daripada di jajak pendapat. Begitu orang terbiasa dengan alternatif ciak itu tidak akan berubah. Bahkan ketika badai merobohkan kekuatannya.
candied_orange

1
Saya akan memberi Anda manfaat dari keraguan atas klaim Anda bahwa "Sebuah domain yang kaya bagus jika dilakukan dengan baik. Mimpi buruk ketika tidak." Mungkin saya belum pernah melihatnya melakukannya dengan baik, Tapi kemudian Anda membuat klaim omong kosong bahwa "Domain anemia selalu buruk." Opini tidak masuk akal membuat jawaban Anda tidak berharga. -1
David Arno
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.