Pertimbangkan sistem yang menggunakan DDD (juga: sistem apa pun yang menggunakan ORM). Inti dari sistem apa pun secara realistis, dalam hampir setiap kasus penggunaan, adalah memanipulasi objek domain tersebut. Kalau tidak, tidak ada efek atau tujuan nyata.
Memodifikasi objek yang tidak dapat diubah akan menyebabkannya untuk menghasilkan catatan baru setelah objek bertahan yang membuat gembung besar dalam sumber data (kecuali Anda menghapus catatan sebelumnya setelah modifikasi).
Saya dapat melihat manfaat dari menggunakan objek yang tidak dapat diubah, tetapi dalam hal ini, saya tidak pernah bisa melihat kasus yang berguna untuk menggunakan objek yang tidak dapat diubah. Apakah ini salah?
immutability
domain-driven-design
Steven Evers
sumber
sumber
Jawaban:
Komputasi dengan menggunakan objek yang tidak dapat diubah (seperti dalam pemrograman fungsional) tidak selalu berarti setiap objek yang dihasilkan tetap ada!
sumber
Apakah tidak berubah dalam domain berarti harus tidak berubah dalam database? Sebagai contoh pertimbangkan hal berikut dengan asumsi pelanggan selalu memiliki satu alamat:
sekarang sql berikut dijalankan mengingat id pelanggan adalah 1:
sekarang perubahan berikut dibuat ke alamat:
dan lapisan kegigihan, menjadi sangat pintar menjalankan sql berikut:
Dengan cara ini Anda menghindari overhead pernyataan DELETE AND INSERT yang terpisah. Juga saya pikir beberapa RDBMS memiliki INSERT REPLACE atau sesuatu. MySql memiliki REPLACE .
sumber
Dalam DDD, objek yang tidak dapat diubah cukup menyamakan dengan objek bernilai. Objek-objek ini bukan entitas, mereka tidak memiliki identitas. Oleh karena itu saya selalu mempertahankan nilai objek sebagai kolom dari entitas tempat mereka berada (dengan N / Hibernate Anda dapat menggunakan Komponen untuk itu). Mereka tidak punya meja sendiri.
sumber
Itu tergantung pada bagaimana objek yang tidak dapat diubah dipetakan dalam database. Jika itu hanya komponen seperti DateTime (dari perpustakaan Joda Time) maka mengubah nilai akan menghasilkan pembaruan daripada menyisipkan. Namun, jika immutable lebih kompleks membutuhkan baris dalam sebuah tabel maka Anda punya masalah mengasapi.
Saya kira, meskipun ini argumen yang lemah, Anda bisa menerapkan jejak audit dengan cara ini. Setiap perubahan pada immmutable dapat dilacak melalui sisipan. Ada banyak cara yang lebih baik untuk melakukan ini.
Semua dalam semua memiliki objek domain abadi (bukan hanya komponen mereka) tampaknya sedikit ketidakcocokan dengan kegigihan.
sumber
Itu tergantung pada domain. DDD tidak menentukan bahwa paradigma pemrograman berorientasi objek. Namun paradigma berorientasi objek sangat cocok untuk aplikasi khas yang harus dipertahankan dalam database.
DDD hanya menyatakan bahwa Anda harus membangun perangkat lunak Anda di sekitar model domain yang mewakili masalah aktual yang coba dipecahkan oleh perangkat lunak. Jika masalah itu misalnya matematis pada dasarnya, maka mengimplementasikan lapisan domain menggunakan pemrograman fungsional dan struktur data yang tidak dapat diubah akan sangat masuk akal.
Jika di sisi lain, masalahnya adalah lebih dari aplikasi perusahaan biasa, dan Anda menggunakan struktur objek yang tidak dapat diubah untuk semua objek domain Anda, maka saya berpendapat bahwa Anda tidak mengikuti DDD. Saya dapat mengajukan setidaknya dua argumen:
Implementasi Anda tidak mewakili model domain dari domain masalah Anda. Domain masalah Anda dalam hal ini terdiri dari entitas yang memiliki status untuk diubah. Dan bukan itu cara Anda menerapkannya.
Anda tidak memiliki bahasa di mana-mana. Bahasa dan konsep dalam model domain tidak mengikuti apa yang digunakan pakar domain.
Catatan: DDD memang menggunakan objek yang tidak dapat diubah di mana sesuai, mereka hanya disebut objek nilai.
Jadi saya tidak mengatakan bahwa Anda tidak dapat membuat aplikasi database menggunakan struktur data yang berfungsi murni, dan saya tidak mengatakan bahwa Anda seharusnya tidak. Saya hanya tidak berpikir Anda bisa menyebutnya DDD, tergantung pada jenis aplikasi
sumber
Jika Anda menggunakan ORM seperti Hibernate / NHibernate Anda dapat mengatur opsi kaskade Anda untuk secara otomatis menghapus objek yatim. Jika seseorang memiliki alamat objek nilai, ketika Anda mengubah alamat, yang baru akan disimpan dan yang lama dihapus karena sekarang menjadi yatim piatu.
sumber
Nilai objek hampir selalu berubah dalam DDD dan pola kelas terbang dapat digunakan untuk menjaga duplikasi objek nilai itu dalam memori seperti halnya .NET lakukan dengan string. Tradeoff utama adalah memori satu sisi dan sisi lain adalah efisiensi penciptaan. Dengan pola kelas terbang, perbandingan berbasis nilai harus dilakukan untuk menentukan apakah objek nilai baru atau yang dilarutkan sudah ada dalam cache kelas terbang tetapi perbandingan lain setelah titik itu secara umum dapat dilakukan dengan aman dengan referensi karena satu contoh diterapkan. Either way apakah kelas terbang digunakan atau tidak, objek nilai masih dibuat abadi karena mereka hanya memiliki identitas intrinsik dan dengan demikian mengubah nilainya akan mengubah identitas mereka.
sumber
Ada cara lain untuk menggunakan objek yang tidak dapat diubah ...
Alih-alih menyimpan nilai 5.0, 6.0, 7.0, 8.0 dan menyalin seluruh catatan setiap kali, Anda dapat menyimpan sesuatu seperti ini: 5.0, +1.0, +1.0, +1.0, dan kemudian membangun dependensi dengan benar untuk merekonstruksi urutan 5.0 , 6.0, 7.0, 8.0. Dengan cara ini, modifikasi kecil hanya membutuhkan sedikit memori ...
sumber