Objek Domain sebagai id membuat beberapa masalah kompleks / halus:
Serialisasi / Deserialisasi
Jika Anda menyimpan objek sebagai kunci, itu akan membuat serialisasi objek grafik menjadi sangat rumit. Anda akan mendapatkan stackoverflow
kesalahan saat melakukan serialisasi naif ke JSON atau XML karena rekursi. Anda kemudian harus menulis serializer khusus yang mengubah objek aktual untuk menggunakan id mereka alih-alih membuat serialisasi objek contoh dan membuat rekursi.
Lewati objek untuk keamanan tipe tetapi hanya menyimpan id, maka Anda dapat memiliki metode pengakses yang malas memuat entitas terkait ketika dipanggil. Caching tingkat kedua akan menangani panggilan berikutnya.
Kebocoran referensi halus:
Jika Anda menggunakan objek domain dalam konstruktor seperti yang Anda miliki di sana, Anda akan membuat referensi melingkar yang akan sangat sulit untuk memungkinkan memori direklamasi untuk objek yang tidak digunakan secara aktif.
Situasi yang ideal:
Id buram vs int / panjang:
Seorang id
harus merupakan pengidentifikasi yang sepenuhnya buram yang tidak membawa informasi tentang apa yang diidentifikasi. Tetapi harus menawarkan beberapa verifikasi bahwa itu adalah pengidentifikasi yang valid dalam sistemnya.
Jenis mentah mematahkan ini:
int
, long
dan String
merupakan jenis mentah yang paling umum digunakan untuk pengidentifikasi dalam sistem RDBMS. Ada sejarah panjang alasan praktis yang berasal dari dekade dan mereka semua adalah kompromi yang cocok dengan tabungan space
atau tabungan time
atau keduanya.
Id berurutan adalah pelanggar terburuk:
Saat Anda menggunakan id berurutan, Anda mengemas informasi semantik temporal ke dalam id secara default. Yang tidak buruk sampai digunakan. Ketika orang mulai menulis logika bisnis yang menyortir atau memfilter pada kualitas semantik id, maka mereka membuat dunia kesakitan bagi para pengelola masa depan.
String
bidang yang bermasalah karena desainer naif akan mengemas informasi ke dalam konten, biasanya semantik temporal juga.
Ini membuat tidak mungkin untuk menciptakan sebuah sistem data terdistribusi juga, karena 12437379123
ini tidak unik global. Peluang bahwa node lain dalam sistem terdistribusi akan membuat catatan dengan nomor yang sama dijamin cukup banyak ketika Anda mendapatkan cukup data dalam suatu sistem.
Kemudian retas mulai bekerja di sekitarnya dan semuanya berubah menjadi tumpukan kekacauan mengepul.
Mengabaikan sistem terdistribusi besar ( cluster ) itu menjadi mimpi buruk lengkap ketika Anda mulai mencoba untuk berbagi data dengan sistem lain juga. Terutama ketika sistem lain tidak di bawah kendali Anda.
Anda berakhir dengan masalah yang sama persis, bagaimana membuat id Anda unik secara global.
UUID dibuat dan distandarisasi karena suatu alasan:
UUID
dapat mengalami semua masalah yang tercantum di atas tergantung pada yang Version
Anda gunakan.
Version 1
menggunakan alamat MAC dan waktu untuk membuat id unik. Ini buruk karena membawa informasi semantik tentang lokasi dan waktu. Itu sendiri bukan masalah, itu adalah ketika pengembang naif mulai mengandalkan informasi itu untuk logika bisnis. Ini juga membocorkan informasi yang dapat dieksploitasi dalam setiap upaya intrusi.
Version 2
menggunakan pengguna UID
atau GID
dan domian UID
atau GUI
sebagai pengganti waktu dari Version 1
ini sama buruknya dengan Version 1
kebocoran data dan mempertaruhkan informasi ini untuk digunakan dalam logika bisnis.
Version 3
serupa tetapi menggantikan alamat MAC dan waktu dengan MD5
hash dari beberapa array byte[]
dari sesuatu yang pasti memiliki makna semantik. Tidak ada kebocoran data yang perlu dikhawatirkan, byte[]
tidak dapat dipulihkan dari UUID
. Ini memberi Anda cara yang baik untuk secara deterministik membuat UUID
bentuk instance dan kunci eksternal semacam itu.
Version 4
didasarkan hanya pada angka acak yang merupakan solusi yang baik, sama sekali tidak membawa informasi semantik, tetapi tidak secara deterministik dapat diciptakan kembali.
Version 5
hanya suka Version 4
tetapi menggunakan sha1
bukan md5
.
Kunci Domain dan Kunci Data Transaksional
Preferensi saya untuk id objek domain, adalah menggunakan Version 5
atau Version 3
jika dibatasi menggunakan Version 5
karena beberapa alasan teknis.
Version 3
sangat bagus untuk data transaksi yang mungkin tersebar di banyak mesin.
Kecuali jika Anda dibatasi oleh ruang, gunakan UUID:
Mereka dijamin unik, membuang data dari satu database dan memuat ulang ke yang lain Anda tidak perlu khawatir tentang duplikat id yang sebenarnya referensi data domain yang berbeda.
Version 3,4,5
benar-benar buram dan begitulah seharusnya.
Anda dapat memiliki satu kolom sebagai kunci utama dengan UUID
dan kemudian Anda dapat memiliki indeks unik gabungan untuk apa yang seharusnya menjadi kunci primer komposit alami.
Penyimpanan juga tidak harus CHAR(36)
. Anda dapat menyimpan UUID
dalam byte asli / bit / angka bidang untuk database yang diberikan selama masih dapat diindeks.
Warisan
Jika Anda memiliki tipe mentah dan tidak bisa mengubahnya, Anda masih bisa mengabstraksikannya dalam kode Anda.
Menggunakan salah satu Version 3/5
dari UUID
Anda dapat lulus dalam Class.getName()
+ String.valueOf(int)
sebagai byte[]
dan memiliki kunci referensi buram yang dapat dipulihkan dan ditentukan.