Mengatasi kenyataan bahwa kunci utama bukan bagian dari domain bisnis Anda

25

Di hampir semua keadaan, kunci utama bukan bagian dari domain bisnis Anda. Tentu, Anda mungkin memiliki beberapa objek penting yang menghadap pengguna dengan indeks unik ( UserNameuntuk pengguna atau OrderNumberuntuk pesanan) tetapi dalam kebanyakan kasus, tidak perlu berbisnis mengidentifikasi objek domain secara terbuka dengan satu nilai atau serangkaian nilai, kepada siapa pun, tetapi mungkin pengguna administratif. Bahkan dalam kasus luar biasa itu, terutama jika Anda menggunakan pengidentifikasi unik global (GUID) , Anda akan lebih suka atau ingin menggunakan kunci alternatif daripada mengekspos kunci primer itu sendiri.

Jadi, jika pemahaman saya tentang desain yang digerakkan oleh domain akurat, kunci primer tidak perlu dan karenanya tidak boleh diekspos, dan baguslah. Mereka jelek dan kram gaya saya. Tetapi jika kita memilih untuk tidak memasukkan kunci utama dalam model domain, ada konsekuensi:

  1. Secara naif, objek transfer data (DTO) yang berasal secara eksklusif dari kombinasi model domain tidak akan memiliki kunci utama
  2. DTO masuk tidak akan memiliki kunci utama

Jadi, apakah aman untuk mengatakan bahwa jika Anda benar-benar akan tetap murni dan menghilangkan kunci utama dalam model domain Anda, Anda harus siap untuk dapat menangani setiap permintaan dalam hal indeks unik pada kunci utama itu?

Dengan kata lain, solusi manakah di bawah ini yang merupakan pendekatan yang tepat untuk berurusan dengan mengidentifikasi objek tertentu setelah menghapus PK dalam model domain?

  1. Mampu mengidentifikasi objek yang perlu Anda tangani dengan atribut lain
  2. Mendapatkan kunci utama kembali di DTO; yaitu, menghilangkan PK saat memetakan dari kegigihan ke domain, lalu menggabungkan kembali PK saat memetakan dari domain ke DTO?

EDIT: Mari kita buat beton ini.

Mengatakan model domain saya VoIPProvideryang meliputi bidang-bidang seperti Name, Description, URL, serta referensi suka ProviderType, PhysicalAddressdan Transactions.

Sekarang katakanlah saya ingin membangun layanan web yang akan memungkinkan pengguna istimewa untuk mengelola VoIPProvider.

Mungkin ID ramah pengguna tidak berguna dalam kasus ini; setelah semua, penyedia VoIP adalah perusahaan yang namanya cenderung berbeda dalam pengertian komputer dan bahkan cukup berbeda dalam pengertian manusia untuk alasan bisnis. Jadi mungkin cukup untuk mengatakan bahwa yang unik VoIPProvidersepenuhnya ditentukan oleh (Name, URL). Jadi sekarang katakanlah saya memerlukan metode PUT api/providers/voipagar pengguna yang istimewa dapat memperbarui VoIPpenyedia. Mereka mengirim VoIPProviderDTO, yang mencakup banyak tetapi tidak semua bidang dari VoIPProvider, termasuk beberapa perataan berpotensi. Namun, saya tidak bisa membaca pikiran mereka, dan mereka masih perlu memberi tahu saya penyedia mana yang sedang kita bicarakan.

Sepertinya saya memiliki 2 (mungkin 3) opsi:

  1. Sertakan kunci utama atau kunci alternatif dalam model domain saya dan kirimkan ke DTO, dan sebaliknya
  2. Identifikasi penyedia yang kami pedulikan melalui indeks unik, seperti (Name, Url)
  3. Memperkenalkan semacam objek perantara yang selalu dapat memetakan antara lapisan kegigihan, domain, dan DTO dengan cara yang tidak mengekspos detail implementasi tentang lapisan kegigihan - katakanlah dengan memperkenalkan pengidentifikasi sementara di dalam memori ketika pergi dari domain ke DTO dan kembali,
tacos_tacos_tacos
sumber
1
Poin untuk direnungkan: sering kali komunikasi dengan pakar domain menjadi miskin ketika pengganti PK digunakan ketika kunci bisnis yang baik ada. Tampaknya kita akhirnya bekerja untuk kerangka kerja ORM, bukannya sebaliknya.
Tulains Córdova
@ user61852 dengan baik terlepas dari ORM, bahkan jika Anda benar-benar tingkat rendah, Anda masih memerlukan kunci utama dalam implementasi lapisan database. Jadi saya setuju bahwa PK pengganti memberi Anda keuntungan dibandingkan PK aktual yang digunakan oleh mekanisme kegigihan tertentu, tetapi jika PK tersebut benar-benar mewakili objek bisnis yang bermakna, itu harus unik dan karenanya memiliki setidaknya satu properti unik terkait bisnis yang mendefinisikan bukan?
tacos_tacos_tacos
1
Semua keunggulan pengganti terkait dengan komputer dan tidak ada yang terkait manusia.
Tulains Córdova
2
@ user61852: Saya setuju 100% (apakah saya menulis sesuatu yang berbeda?). Untuk sarana komunikasi, gunakan "kunci bisnis". Tambahkan kendala unik untuk kunci bisnis apa pun juga. Tetapi hindari penggunaan kunci bisnis untuk benar-benar mengimplementasikan referensi basis data Anda.
Doc Brown
2
kunci bisnis selamanya unik - sampai tidak ada. Jika Anda menggunakan kunci bisnis sebagai hal utama saat ini terjadi maka perubahan dalam aturan bisnis memecah lebih banyak barang.
psr

Jawaban:

31

Inilah cara kami memecahkan masalah ini (sejak lebih dari 15 tahun, bahkan ketika istilah "desain yang didorong oleh domain" tidak ditemukan):

  • saat memetakan model domain ke implementasi database atau model kelas dalam bahasa pemrograman tertentu, Anda memiliki aturan sederhana dan konsisten seperti "untuk setiap objek domain yang dipetakan ke tabel relasional, kunci utama adalah" TablenameID ".
  • kunci utama ini sepenuhnya buatan, selalu memiliki tipe yang sama, dan tidak ada arti bisnis - hanya kunci pengganti
  • "versi grafis" dari model domain Anda (yang Anda gunakan untuk berbicara dengan pakar domain Anda) tidak mengandung kunci utama. Anda tidak memaparkannya langsung ke para ahli (tetapi Anda memaparkannya kepada siapa pun yang sebenarnya menerapkan kode untuk sistem).

Jadi, setiap kali Anda membutuhkan kunci utama untuk tujuan teknis (seperti memetakan hubungan ke database), Anda memiliki satu tersedia, tetapi selama Anda tidak ingin "melihatnya", ubah tingkat abstraksi Anda ke "model pakar domain" ". Dan Anda tidak harus mempertahankan "dua model" (satu dengan PK dan satu tanpa); alih-alih, pertahankan hanya model tanpa PK dan gunakan pembuat kode untuk membuat DDL untuk DB Anda, yang menambahkan PK secara otomatis sesuai dengan aturan pemetaan.

Perhatikan bahwa ini tidak melarang untuk menambahkan "kunci bisnis" seperti "OrderNumber" tambahan, selain pengganti OrderID. Secara teknis, kunci bisnis ini menjadi kunci alternatif saat memetakan ke basis data Anda. Hanya menghindari menggunakan ini untuk membuat referensi ke tabel lain, selalu lebih suka menggunakan kunci pengganti jika memungkinkan, ini akan membuat segalanya jauh lebih mudah.

Untuk komentar Anda: menggunakan kunci pengganti untuk mengidentifikasi catatan bukanlah operasi yang terkait dengan bisnis, ini adalah operasi yang murni teknis. Untuk memperjelas ini, lihat contoh Anda: selama Anda tidak mendefinisikan batasan unik lainnya, akan mungkin untuk memiliki dua objek VoIPProvider dengan kombinasi yang sama (nama, url), tetapi berbeda VoIPProviderIDs.

Doc Brown
sumber
Bagaimana dengan langkah mengambil objek domain dari objek kegigihan yang dikembalikan (entitas, atau model baris tabel, atau apa pun), pergi ke DTO, dan membawanya kembali, dan kembali ke kegigihan? Apakah ini hanya dilakukan melalui kunci pengganti (yaitu definisi keunikan yang berorientasi bisnis) yang memerlukan resolusi pada setiap operasi ketekunan?
tacos_tacos_tacos
1
@tacos_tacos_tacos: mari ikuti contoh VoIPProvider Anda. Saya sebenarnya akan menambahkan "VoIPProviderID" ke DTO Anda, setidaknya di "sisi implementasi" (jika Anda juga memiliki versi grafis untuk pakar domain Anda, saya mungkin tidak akan menunjukkannya di sana). Untuk tujuan memperbarui, cara standar untuk mengidentifikasi Penyedia VoIP tertentu harus dengan "VoIPProviderID" yang Anda ambil ketika menarik data dari database. Jika pengguna API Anda lebih suka identifikasi berdasarkan (nama, URL), berikan itu tambahan. ...
Doc Brown
... dan jika kinerja tampaknya menjadi masalah nyata yang dapat diukur, Anda juga dapat mempertimbangkan untuk melakukan cache pemetaan (nama, url) ke VoIPProviderID di suatu tempat. Tetapi saya tidak akan merekomendasikan untuk mengimplementasikan optimasi seperti itu sebelumnya, sebelum waktunya.
Doc Brown
1
Kunci alami kadang-kadang tampak sangat menarik tetapi terlalu mudah untuk dibakar (misalnya, "wah, sekarang saya memiliki beberapa penyewa dan itu tidak lagi unik").
Casey
1
@corsiKa: dalam konteks apa yang ditanyakan OP, saya akan sangat menyarankan untuk memiliki kunci murni murni "OrderID" (yang tidak dicetak pada tanda terima apa pun, tetapi hanya digunakan untuk hal-hal internal seperti referensi basis data), dan kunci bisnis terpisah "OrderNumber" (yang dapat, misalnya, berisi sesuatu seperti tahun ini, yang dapat digunakan untuk menyortir dan memfilter, yang dapat diubah / diperbaiki setelahnya, dan yang dapat dicetak pada tanda terima). OP meminta "Desain Berbasis Domain", "OrderNumber" adalah bagian dari model domain, sementara "OrderID" hanyalah detail implementasi.
Doc Brown
4

Anda harus dapat mengidentifikasi banyak objek dengan beberapa indeks unik, dan bukankah itu yang menjadi kunci utama (atau setidaknya menyiratkan ada satu).

Indeks unik tersedia sehingga Anda dapat lebih lanjut membatasi skema DB Anda, bukan sebagai pengganti grosir untuk PK. Jika Anda tidak mengekspos PK karena mereka jelek, tetapi mengekspos kunci yang unik sebagai gantinya ... Anda sebenarnya tidak melakukan sesuatu yang berbeda. (Saya menganggap Anda tidak mendapatkan PK dan kolom identitas dicampur di sini?)

gbjbaanb
sumber
Ketika saya ingin melakukan operasi yang melibatkan contoh spesifik dari objek domain yang bertahan, saya harus dapat memasukkan dalam DTO baik secara eksplisit (melalui semacam kunci, baik primer atau ID ramah pengguna alternatif yang unik ke tabel itu dan mungkin juga menjadi indeks di atas meja) atau secara implisit (melalui beberapa kombinasi bidang yang nilainya secara unik mengidentifikasi catatan tertentu) ... dan lebih jauh lagi, dalam arti praktis, saya perlu mengirim di DTO beberapa bentuk pelacakan perubahan jika saya melakukannya dengan cara lain (OriginalVal vs NewVal untuk semua bidang yang mengidentifikasi catatan), bukan?
tacos_tacos_tacos
bukankah pertanyaan eksplisit v implisit perbedaan yang sama? Anda dapat memiliki PK yang mencakup beberapa kolom, seperti indeks yang unik. Saya tidak melihat ada perbedaan di antara mereka untuk tujuan Anda.
gbjbaanb
Tentu, kami dapat memiliki PK pada beberapa kolom misalnya. Tetapi bagi saya itu bocor sesuatu tentang databaswe (penyimpanan) yang seharusnya tidak ada hubungannya dengan hati & jiwa, entitas bisnis. Jika beberapa bidang entitas bisnis terjadi untuk rentang PK untuk DB, maka bagus. Tetapi seharusnya tidak harus sebaliknya, bukan?
tacos_tacos_tacos
Anda terlalu memikirkannya. Indeks unik adalah artefak skema DB sama seperti PK. Pikirkan seperti ini - PK hanyalah indeks unik pertama (atau primer). ini 'istimewa' karena umumnya Anda hanya memerlukan 1 indeks tersebut.
gbjbaanb
Benar, tetapi objek domain apa pun yang berarti harus dapat diidentifikasi secara ketat dari setidaknya satu bidang yang terkait dengan bisnisnya, bukan? Fakta bahwa ini mendefinisikan indeks dalam DB lebih karena alasan kinerja daripada digunakan untuk query DB dengan mudah ... Saya lebih suka PK satu kolom daripada indeks unik 6-kolom, dan mereka benar-benar melayani tujuan yang berbeda - sebuah PK (atau indeks dengan sejumlah kecil bidang) juga tersedia untuk kenyamanan DBA / DBD, bukan?
tacos_tacos_tacos
4

Tanpa kunci primer di frontend, tidak ada cara mudah bagi backend untuk mengetahui apa yang Anda kirim. Untuk memperbaikinya, Anda akan membutuhkan satu ton pekerjaan tambahan untuk mengurai data, yang akan merusak kinerja dan mungkin membutuhkan waktu lebih lama dan lebih buruk daripada melampirkan kunci ke setiap item.

Sebagai contoh, katakanlah saya ingin mengedit pesan di aplikasi; bagaimana aplikasi mengetahui pesan mana yang ingin saya edit tanpa kunci primer terpasang? Mengedit objek terjadi setiap saat dan melakukan itu tanpa kunci hampir tidak mungkin. Tetapi jika Anda memiliki objek yang tidak seharusnya diedit kemudian lewati tombol jika Anda pikir itu mengganggu, tetapi memiliki kunci primer dapat meningkatkan kinerja di sini.

Johan
sumber
Nah, pesan adalah contoh ekstrim, tetapi bahkan kemudian kita akan tahu MessageSender, MessageRecipient, TimeSent- yang harus unik.
tacos_tacos_tacos
1
@tacos_tacos_tacos, lalu bagaimana Anda membuat FK ke tabel lain? Itu harus MessageSenderId, yang mungkin memetakan ke tabel Pengguna di UserId. Anda tidak ingin menggunakan UserName sebagai kunci di antara tabel, karena itu bisa berubah dan menjadi mimpi buruk pemeliharaan. Inilah sebabnya mengapa Anda umumnya hanya bergabung dengan tabel menggunakan Kunci Utama, dan bukan kolom lain (tentu saja ada pengecualian). Struktur db ini masih harus ditegakkan. Sekarang Anda selalu bisa pergi ke model CQRS untuk aplikasi Anda ... dalam hal ini peraturan berubah. Terutama jika Anda juga menggunakan Sumber Acara.
CaffGeek
4

Alasan kami menggunakan PK terkait non-bisnis adalah untuk memastikan bahwa sistem kami memiliki metode yang mudah dan konsisten untuk menentukan apa yang diinginkan pengguna.

Saya melihat Anda menjawab dengan komentar: MessageSender, MessageRecipient, TimeSent (untuk sebuah pesan). Anda dapat MASIH memiliki ambiguitas dengan cara ini (misalnya, dengan pesan yang dihasilkan sistem memicu sesuatu yang sering terjadi). Dan bagaimana Anda akan memvalidasi MessageSender dan MessageRecipient di sini? Misalkan Anda memvalidasi mereka menggunakan FirstName, Lastname, DateOfBirth, Anda pada akhirnya akan mengalami situasi di mana Anda memiliki 2 orang yang lahir pada hari yang sama dengan nama yang sama persis. Belum lagi Anda akan mengalami situasi di mana Anda memiliki pesan bernama tacostacostacos-America-1980-Doc Brown-France-1965-23/5/2014-11:43:54.003UTC+200. Itu monster dari sebuah nama, dan Anda masih tidak memiliki jaminan Anda hanya akan memiliki 1 dari itu.

alasan kami menggunakan kunci utama adalah karena kami TAHU itu akan menjadi unik selama masa pakai perangkat lunak, tidak peduli data apa yang dimasukkan, dan kami TAHU itu akan menjadi format yang dapat diprediksi (apa yang terjadi jika kunci Anda di atas memiliki tanda hubung dalam nama pengguna? seluruh sistem Anda digunakan)

Anda tidak perlu menunjukkan ID Anda kepada pengguna Anda. Anda dapat menyembunyikannya (terlihat jelas jika perlu, melalui URL).

Alasan lain mengapa PK sangat berguna adalah sesuatu yang dapat Anda simpulkan dari hal di atas: PK membuatnya sehingga Anda tidak perlu memaksa komputer untuk menafsirkan kode yang dibuat pengguna. Jika pengguna China menggunakan kode Anda dan memasukkan banyak karakter Cina, kode Anda tiba-tiba tidak perlu dapat bekerja dengan ini secara internal, tetapi hanya dapat menggunakan Panduan yang dihasilkan sistem. Jika Anda memiliki pengguna Arab yang memasuki tulisan Arab, sistem Anda tidak harus mengatasinya secara internal, tetapi pada dasarnya dapat mengabaikan bahwa mereka ada di sana.

Seperti yang dikatakan orang lain, Guid adalah sesuatu yang dapat disimpan secara internal dalam ukuran tetap. Anda tahu apa yang Anda kerjakan dan itu adalah sesuatu yang dapat digunakan secara universal. Anda tidak perlu membuat aturan desain tentang cara membuat pengenal tertentu dan menyimpannya. Jika sistem Anda hanya menggunakan 10 huruf pertama dari sebuah nama, itu tidak melihat perbedaan antara Michael Guggenheimer dan Michael Gugstein, dan itu akan membingungkan 2 ini. Jika Anda memotongnya pada panjang yang sewenang-wenang, Anda dapat mengalami kebingungan. Jika Anda membatasi input pengguna, Anda dapat mengalami masalah dengan keterbatasan pengguna.

Ketika saya melihat sistem yang ada seperti Dynamics CRM, mereka juga menggunakan kunci internal (PK) bagi pengguna untuk memanggil satu catatan. Jika pengguna memiliki kueri yang tidak melibatkan ID, mereka mengembalikan serangkaian jawaban yang mungkin dan membiarkan pengguna memilihnya. Jika ada kemungkinan ambiguitas, mereka akan memberikan pilihan kepada pengguna.

Akhirnya, itu juga keamanan melalui ketidakjelasan. Jika Anda tidak tahu ID rekaman, satu-satunya pilihan adalah menebaknya. jika ID mudah ditebak (karena informasi yang dibuatnya tersedia untuk umum), siapa pun dapat mengubahnya. Anda bahkan dapat mendorong pengguna untuk mengubahnya melalui metode CSRF atau XSS klasik. Sekarang, jelas keamanan Anda seharusnya sudah diperhitungkan dan dimitigasi sebelum pernah menerbitkan versi live, tetapi Anda harus tetap mempersulit potensi penyalahgunaan terjadi.

Nzall
sumber
1

Saat mengeluarkan pengidentifikasi untuk sistem eksternal, Anda hanya harus memberikan URI, atau alternatif kunci atau seperangkat kunci yang memiliki sifat yang sama dengan URI, daripada membuka kunci primer basis data secara langsung (dari sini dan seterusnya saya akan merujuk ke baik URI atau kunci atau serangkaian kunci yang memiliki properti yang sama dengan URI dengan hanya URI, dengan kata lain URI di bawah ini tidak selalu berarti RFC 3986 URI).

URI mungkin atau mungkin tidak mengandung kunci utama objek dan itu mungkin atau mungkin tidak benar-benar terdiri dari kunci alternatif. Itu tidak masalah. Yang penting adalah bahwa hanya sistem yang menghasilkan URI diizinkan untuk membagi atau menggabungkan URI untuk membentuk pemahaman tentang apa objek yang dimaksud. Sistem eksternal harus selalu menggunakan URI sebagai pengidentifikasi buram. Tidak masalah jika pengguna manusia dapat mengidentifikasi bahwa salah satu bagian dari URI sebenarnya adalah kunci pengganti basis data atau bahwa itu terdiri dari beberapa kunci bisnis yang dikelompokkan bersama, atau bahwa itu sebenarnya adalah basis64 dari nilai-nilai itu. Ini tidak relevan. Yang penting adalah bahwa sistem eksternal tidak perlu diminta untuk memahami apa arti pengidentifikasi untuk menggunakan pengidentifikasi. Sistem eksternal tidak boleh diminta untuk mengurai komponen dalam pengidentifikasi atau menggabungkan pengidentifikasi dengan pengidentifikasi lain untuk merujuk pada sesuatu di sistem Anda.

Menggunakan GUID memenuhi beberapa kriteria ini, namun pengidentifikasi seperti GUID bisa sulit untuk kembali ke objek bahkan di dalam sistem Anda, jadi kunci yang buram bahkan sistem Anda seperti GUID hanya boleh digunakan jika klien menguraikan URI / pengidentifikasi sebenarnya menimbulkan risiko keamanan.

Kembali ke contoh VoIP Anda, katakan bahwa penyedia VoIP dapat ditentukan secara unik baik oleh (VoIPProviderID) atau dengan (Nama, URL) atau dengan (GUID). Ketika sistem eksternal perlu memperbarui penyedia VoIP, itu hanya dapat melewati PUT / provider / by-id / 1234 atau PUT /provider/foo-voip/bar-domain.comatau PUT /3F2504E0-4F89-41D3-9A0C-0305E82C3301dan sistem Anda akan memahami bahwa sistem eksternal ingin memperbarui VoIPProvider. URI ini dihasilkan oleh sistem Anda dan hanya sistem Anda yang perlu memahami bahwa semua itu berarti hal yang sama. Sistem eksternal harus memperlakukan apa saja yang ada di URI pada dasarnya a PUT <whatever>.

Misalkan Anda memiliki data untuk penyedia VoIP yang berbeda yang disimpan dalam tabel yang berbeda dengan skema yang berbeda (dengan demikian rangkaian kunci yang berbeda mengidentifikasi setiap penyedia VoIP berdasarkan tabel tempat penyimpanan mereka). Ketika Anda memiliki URI, mereka dapat diakses secara seragam oleh sistem eksternal, tanpa memperhatikan bagaimana sistem Anda mengidentifikasi penyedia VoIP tertentu. Untuk sistem eksternal itu semua hanya pointer buram.

Ketika sistem Anda menggunakan URI untuk merujuk ke objek sedemikian rupa, Anda tidak membocorkan apa pun tentang bagaimana Anda menerapkan sistem Anda. Anda menghasilkan URI dan klien hanya memberikannya kembali kepada Anda.

Lie Ryan
sumber
0

Saya harus menargetkan pernyataan yang sangat tidak akurat dan naif ini:

Mungkin ID ramah pengguna tidak berguna dalam kasus ini; setelah semua, penyedia VoIP adalah perusahaan yang namanya cenderung berbeda dalam pengertian komputer dan bahkan cukup berbeda dalam pengertian manusia untuk alasan bisnis.

Nama-nama mengerikan seperti kunci, karena sering berubah. Perusahaan mungkin memiliki banyak nama selama masa hidupnya, perusahaan dapat menggabungkan, membagi, menggabungkan lagi, membuat anak perusahaan yang berbeda untuk keperluan pajak khusus yang memiliki 0 karyawan tetapi semua pelanggan yang kemudian mempekerjakan karyawan dari anak perusahaan yang sama sekali berbeda.

Kemudian kita masuk ke fakta bahwa nama perusahaan bahkan tidak unik, seperti yang ditunjukkan oleh tengara Apple vs Apple .

Mapper relasional atau kerangka kerja objek yang baik harus mengabstraksi kunci primer dan membuatnya tidak terlihat, tetapi mereka ada di sana, dan mereka biasanya akan menjadi satu - satunya cara untuk secara unik mengidentifikasi objek dalam database Anda.

Untuk referensi, saya lebih suka bagaimana Django menangani ini:

class VoipProvider(models.Model):
    name=fields.TextField()
    address=fields.TextField()

class Customer(models.Model):
    name=fields.TextField()
    address=fields.TextField()
    voipProvider=fields.ForeignKeyField(VoipProvider)

Dengan cara ini, detail penyedia pelanggan dapat diakses dalam kode dengan menggunakan:

myCustomer.voipProvider.name #returns the name of the customers VOIP Provider.

Meskipun kunci Utama / Asing tidak terlihat, mereka ada di sana, dan dapat digunakan untuk mengakses item, tetapi disarikan.


sumber
Anda memang benar, tapi saya rasa saya maksudkan bahwa "di beberapa domain, mungkin ada tuple nilai yang selalu unik" Jika mereka berubah, tetapi mereka masih unik, mereka masih mengidentifikasi satu catatan.
tacos_tacos_tacos
0

Saya pikir kita sering masih salah melihat masalah ini dari perspektif DB: oh, tidak ada kunci alami, jadi kita perlu membuat kunci pengganti. Oh tidak, kami tidak dapat membuka kunci pengganti kembali ke objek domain, itu bocor dll.

Namun, terkadang sikap yang lebih baik adalah ini: jika objek bisnis (domain) tidak memiliki kunci alami, maka mungkin harus diberikan satu. Ini adalah masalah domain bisnis dua kali lipat: Pertama, hal-hal memerlukan identitas, bahkan tanpa adanya database. Kedua, walaupun kami mencoba berpura-pura kegigihan adalah ide abstrak yang tidak terlihat oleh domain, kenyataannya adalah bahwa kegigihan masih merupakan konsep bisnis. Jelas, ada masalah di mana kunci alami yang dipilih tidak didukung oleh DB sebagai kunci utama (misalnya GUID pada beberapa sistem) - dalam hal ini Anda perlu menambahkan kunci pengganti.

Dengan demikian, Anda berakhir di tempat yang sangat mirip, misalnya pelanggan Anda memiliki ID integer, tetapi bukannya merasa sakit karena telah bocor dari DB ke domain, Anda merasa senang karena bisnis telah sepakat bahwa semua pelanggan akan diberi ID, dan Anda tetap menggunakannya untuk DB, seperti yang harus Anda lakukan. Anda masih bebas untuk memperkenalkan pengganti, misalnya untuk mendukung penggantian nama ID pelanggan.

Pendekatan ini juga berarti bahwa jika objek domain menyentuh lapisan persistensi, dan tidak memiliki ID, maka itu mungkin semacam objek nilai, jadi tidak perlu ID.

Pucat
sumber