Ini sedikit masalah
Memiliki entitas, dengan objek nilai. Bukan masalah. Saya mengganti objek nilai untuk yang baru, lalu nhibernate menyisipkan nilai baru dan yatim piatu yang lama, lalu menghapusnya. Ok, itu masalah.
Tertanggung adalah entitas saya di domain saya. Dia memiliki koleksi Alamat (objek nilai). Salah satu alamat adalah Alamat Mailing. Ketika kita ingin memperbarui alamat surat, misalkan kode pos salah, mengikuti doktrin Tn. Evans, kita harus mengganti objek lama dengan yang baru karena tidak dapat diubah (objek nilai kan?).
Tapi kami tidak ingin menghapus baris Anda, karena PK alamat itu adalah FK di tabel MailingHistory. Jadi, mengikuti doktrin Tn. Evans, kita benar-benar kacau disini. Kecuali saya membuat Entitas addressses saya, jadi saya tidak perlu "menggantinya", dan cukup perbarui anggota kode posnya, seperti masa lalu yang baik.
Apa yang akan Anda sarankan untuk saya dalam kasus ini? Cara saya melihatnya, ValueObjects hanya berguna ketika Anda ingin merangkum sekelompok kolom tabel database (komponen dalam nhibernate). Segala sesuatu yang memiliki id kegigihan dalam database, lebih baik membuatnya menjadi Entity (tidak harus merupakan agregat root) sehingga Anda dapat memperbarui anggotanya tanpa membuat ulang seluruh objek grafik, terutama jika itu objek bersarang.
Apakah Anda setuju? Apakah diizinkan oleh Tn. Evans untuk memiliki objek nilai yang dapat berubah? Atau objek nilai yang bisa berubah kandidat untuk Entitas?
Terima kasih
sumber
Jawaban:
Segala sesuatu yang memiliki identitas harus menjadi Entitas, dan segala sesuatu yang tidak memiliki identitas adalah nilai sederhana, karenanya merupakan objek nilai.
Mengutip Martin Fowler (yang pada gilirannya Qoutes Eric Evans)
Alasan menjadikan alamat Anda sebagai Objek Nilai:
Jika alamat Anda bisa berubah, Anda mungkin akan mengacaukan riwayat pengiriman surat Anda pada akhirnya. Misalnya, jika Anda mengirim barang ke pelanggan, Anda tidak dapat memastikan ke alamat mana Anda benar-benar mengirim sesuatu di masa lalu jika alamat yang dirujuk oleh tabel MailingHistory Anda telah diubah.
Entri MailingHistory Kami mengirim A764 ke alamat 657 bisa berarti Kami mengirim artikel A764 ke Boston kemarin dan Kami mengirim artikel A764 ke New York besok.
Jika alamat surat harus diubah, tidak perlu menghapus yang lama. Simpan, dan tandai sebagai tidak aktif , dan yang baru aktif .
Tentu saja Anda dapat memperlakukan alamat Anda sebagai Entitas, tetapi hanya saat memperbarui itu tidak akan mengubah tempat sebenarnya yang dirujuk oleh alamat, karenanya hanya mengizinkan koreksi kesalahan ketik.
Jika Anda yakin dapat memastikan hal itu, daripada menggunakan Entitas adalah mungkin.
Tetapi solusi terbaik IMHO adalah tidak mereferensikan Entitas alamat dalam riwayat pengiriman surat Anda, melainkan menyimpan alamat khusus secara langsung di tabel riwayat pengiriman surat Anda (pada dasarnya menyalin data alamat).
Dengan cara ini, Anda selalu tahu di mana Anda mengirim barang-barang Anda (atau apa pun yang Anda kirim), dan karena Anda akan menggunakan Entitas yang bisa berubah, tabel alamat Anda tidak akan berantakan.
Saya telah bekerja dengan / pada beberapa sistem ERP, dan hampir semuanya menggunakan pendekatan ini.
Anda akan memiliki beberapa redundansi di database Anda, tetapi ini adalah cara IMHO yang paling pragmatis.
sumber
ALTER
, menggunakan entitas dalam tabel terpisah mungkin menjadi perlu. Itu, pada gilirannya, panggilan untuk strategi seperti "selalu bergabung dengan terbaru alamat / telepon / e-mail" dalamSELECT
pertanyaan, yang menantang untuk menjaga dipertahankan dan efisien. Sederhanakan, jika memungkinkan.active
-flag. Tentu saja Anda harus memastikan untuk selalu menggunakanand active = true
dalam Bergabung Anda, menjaga bendera tetap up-to-date dan menambahkan contraint ke meja Anda sehingga mis. Hanya satu email untuk setiap pelanggan dapat memiliki bendera ini disetel ke true.active=true
. Ini bukan apa yang saya sebut sederhana, itulah sebabnya saya suka solusi Anda.Saya melihat 2 hal:
Apakah boleh mengubah kode pos untuk memengaruhi catatan riwayat? Saya pikir akan logis jika catatan sejarah menunjuk ke alamat lama yang tidak diubah, sehingga Anda tahu Anda mengirimnya ke alamat yang salah.
Saat MailingHistory memiliki FK pada alamat, alamat berhenti menjadi objek nilai dan menjadi entitas. Objek nilai tidak memiliki identitas, yang memungkinkan entitas lain mereferensikan identitas ini. Anda dapat memiliki alamat dalam satu tabel dengan tabel lain menunjuk ke sana, tetapi hanya efeknya yang menghemat ruang. Dari sudut pandang domain, jika dua entitas memiliki referensi yang sama jenis objek nilai, maka mereka tidak berbagi informasi apa pun.
sumber
IMO objek alamat adalah entitas di domain Anda. Ini dibagikan oleh banyak entitas, memiliki identitas sendiri dan unik di seluruh sistem.
Evans mengatakan:
sumber