Apa sebenarnya ketidaktahuan yang gigih itu?

Ketidaktahuan persistensi biasanya didefinisikan sebagai kemampuan untuk bertahan & mengambil objek .NET standar (atau POCO jika Anda benar-benar bersikeras untuk memberinya nama). Dan definisi objek .NET standar yang tampaknya diterima dengan baik adalah :

"...kelas biasa di mana Anda fokus pada masalah bisnis yang ada tanpa menambahkan hal-hal karena alasan terkait infrastruktur..."

Namun, saya melihat orang menggambarkan NHibernate sebagai kerangka kerja yang memungkinkan ketidaktahuan persistensi, namun ini adalah kerangka kerja yang tidak dapat bekerja pada objek .NET standar apa pun, hanya objek .NET standar yang mematuhi persyaratan desain tertentu, misalnya (sumber):

  • Semua kelas harus memiliki konstruktor default
  • Beberapa fitur tidak berfungsi kecuali kelas dibuka segelnya dan semua anggotanya virtual
  • Identitas objek tidak berfungsi dengan baik kecuali Anda menyalahgunakan Equals/GetHashCode

(Selain itu: Sebelum ada yang marah, saya tidak bermaksud memilih NHibernate di sini, ini hanya contoh kerangka kerja yang sering dikutip yang konon mengizinkan ketidaktahuan persistensi. Saya yakin argumen serupa dapat diterapkan pada ORM lain yang mengklaim hal yang sama.)

Sekarang meskipun kelas itu sendiri tidak memiliki atribut khusus kerangka kerja persistensi atau kelas dasar, dll., bagi saya kelas ini sebenarnya bukan "ketidaktahuan persistensi" karena kelas tersebut harus mengikuti serangkaian pedoman desain untuk memfasilitasi digunakan oleh kerangka persistensi yang dipilih. Anda harus merancang dan mengimplementasikan kelas dengan mempertimbangkan persyaratan kerangka persistensi; jika Anda tidak mengetahuinya, kelas mungkin tidak akan mengerjakannya.

Masalah yang saya hadapi dengan definisi "ketidaktahuan kegigihan"/"POCO" adalah saya tidak melihat bagaimana, secara konseptual, ini benar-benar berbeda dengan menambahkan atribut seperti [Serializable] atau [DataContract] atau [XmlType] atau kerangka kegigihan lainnya - anotasi spesifik yang memfasilitasi persistensi dan pengambilan entitas menggunakan kerangka kerja tersebut.

Jadi, apa sebenarnya "ketidaktahuan yang terus-menerus" itu?

Jelas definisinya sebagai kemampuan untuk mempertahankan "kelas biasa" adalah sebuah kekeliruan karena kelas NHibernate hanya biasa sejauh tidak mereferensikan kelas khusus kerangka kerja, padahal kelas tersebut luar biasa karena memerlukan pilihan desain yang tidak biasa seperti konstruktor default dan semuanya. -anggota virtual dan implementasi Equals/GetHashCode pada tipe yang bisa berubah.

Oleh karena itu, apakah masuk akal untuk mengatakan bahwa "ketidaktahuan persistensi" benar ketika objek memfasilitasi penggunaan kerangka persistensi (baik dalam desain dan struktur atau dengan menggunakan anotasi khusus kerangka kerja) tetapi tidak menjalankan logika persistensi itu sendiri?


person Greg Beech    schedule 29.12.2009    source sumber
comment
Jangan bingung dengan Ketidaktahuan yang Terus-menerus - yang menggambarkan beberapa orang yang saya kenal ;)   -  person Amadiere    schedule 29.12.2009
comment
Bagaimana seharusnya identitas objek berfungsi tanpa kode sama dengan/getash? Bisakah Anda memberi contoh dalam kode psuedo?   -  person Paco    schedule 29.12.2009
comment
Apakah ada orang di luar sana yang benar-benar berpikir bahwa NHibernate (atau ORM lainnya) adalah solusi PI 100%? Inti pertanyaan (yang menarik) adalah kompromi PI mana yang paling mengganggu pengembangan model domain?   -  person Jeff Sternal    schedule 29.12.2009
comment
@Jeff - itu pertanyaan yang lebih menarik - Anda mungkin harus menanyakannya ;-). Misalnya, saya mungkin berpendapat bahwa menambahkan atribut ke kelas domain bukanlah kompromi terhadap PI daripada menambahkan kelas semata-mata untuk membuat ORM senang (yang harus saya lakukan dengan FNH).   -  person Tom Bushell    schedule 29.12.2009
comment
Aee juga: stackoverflow.com/ pertanyaan/905498/   -  person Stefan Steinegger    schedule 06.12.2017


Jawaban (8)


Saya berpendapat bahwa, seperti kebanyakan hal, ini adalah skala geser. Ada hal-hal yang kita buat yang ingin memiliki sifat kegigihan. Di satu sisi, ada hal yang memiliki semua keberanian, ketergantungan, dan kode yang dibuat khusus untuk mempertahankan satu hal ini dengan caranya yang khusus. Di sisi lain, ada sesuatu yang terjadi secara ajaib, tanpa kita melakukan lebih dari sekadar menambahkan token atau menyetel properti di suatu tempat yang menyebabkan hal tersebut 'bertahan'. Untuk mencapai sisi magis dari skala tersebut, ada kerangka kerja, pedoman desain, konvensi, dll yang membantu terjadinya keajaiban. Saya rasa Anda dapat berargumen bahwa alat dapat diproduksi yang memiliki persyaratan dan batasan lebih sedikit daripada NHibernate tetapi memiliki tujuan yang sama; alat hipotetis itu akan lebih sesuai dengan skala kita.

Saya tidak tahu apakah saya begitu menyukai istilah 'ketidaktahuan yang terus-menerus'; ini sebenarnya tentang sebuah objek yang tidak mengetahui implementasinya, penyimpanan pendukung, cache, hal-hal semacam itu - sebuah objek biasanya menyadari apakah objek tersebut persisten atau tidak. Tapi itu hanya semantik.

person Mikeb    schedule 29.12.2009

Saya tidak yakin pemahaman (atau definisi) Anda tentang "Persistence Ingorance" salah.

Masalah sebenarnya adalah abstraksi yang bocor . Sederhananya, teknologi yang ada membuat sangat sulit menerapkan PI yang sebenarnya.

person Vijay Patel    schedule 29.12.2009

Saya setuju dengan Mikeb - "ketidaktahuan kegigihan" adalah skala geser, bukan properti benar/salah dari ORM tertentu.

Definisi saya tentang PI 100% yang sebenarnya adalah Anda dapat mempertahankan kelas POCO APAPUN yang mungkin, tidak peduli seberapa berbelit-belit dan terkait dengan kelas lain, tanpa mengubah kelas dengan cara apa pun.

Menambahkan bidang ID, mendekorasi dengan atribut, mewarisi dari kelas ORM, harus mendesain kelas Anda sehingga dapat dipetakan dengan baik ke tabel dasar dalam RDB - semuanya mengurangi "skor PI" di bawah 100%.

Oleh karena itu, saya memilih untuk menggunakan Fluent NHibernate Automapping karena tampaknya ini memiliki skor PI tertinggi dari semua opsi ORM yang pernah saya lihat.

person Tom Bushell    schedule 29.12.2009
comment
+1 setuju - tidak ada solusi PI yang 100% di luar sana, jadi Anda perlu bertanya pada diri sendiri pertanyaan yang diajukan Jeremy Miller dalam artikelnya (dikutip dalam pertanyaan): Dapatkah Logika Bisnis Berjalan Secara Independen dari Basis Data?, Dapatkah Saya Mendesain Domain Saya Membuat Model Secara Independen dari Model Basis Data?, dan Bagaimana Strategi Persistensi Saya Mempengaruhi Logika Bisnis Saya? - person Jeff Sternal; 29.12.2009

Kelas bodoh yang persisten, adalah kelas yang tidak terikat pada kerangka persistensi.

Artinya, kelas tersebut sama sekali tidak memiliki pengetahuan bahwa terdapat kerangka persistensi, kelas tersebut tidak mewarisi kelas yang ditentukan oleh kerangka tersebut, juga tidak mengimplementasikan antarmuka yang diperlukan agar kerangka persistensi tersebut dapat berfungsi.

person Frederik Gheysels    schedule 29.12.2009
comment
@Frederik - Jadi dengan definisi itu Anda mengatakan bahwa NHibernate tidak mendukung ketidaktahuan yang terus-menerus? Seolah-olah kelas tidak memerlukan konstruktor default untuk penggunaan normal, apakah kelas tersebut masih harus memiliki konstruktor murni karena pengetahuan tentang persyaratan kerangka persistensi? - person Greg Beech; 29.12.2009
comment
Nah NHib juga mengharuskan properti dll dideklarasikan sebagai virtual. Tapi saya tidak akan mengatakan ini benar-benar mempengaruhi ketidaktahuan, karena persyaratannya sangat kecil dan tidak mempengaruhi desain Anda sama sekali. - person UpTheCreek; 29.12.2009
comment
@Greg: tidak, saya tidak mengatakan itu. Saya mengatakan bahwa ketidaktahuan persistensi adalah, jika kelas Anda tidak memerlukan 'referensi' ke kerangka persistensi tersebut. Memang, fakta bahwa Anda memerlukan konstruktor default (yang bisa bersifat pribadi), adalah sebuah kesalahan, tetapi itu tidak berarti bahwa itu bukan ketidaktahuan tentang kegigihan. - person Frederik Gheysels; 29.12.2009
comment
@Sosh: salah. NH tidak mengharuskan properti dideklarasikan sebagai virtual. Saya menggunakan NH setiap hari, dan saya benci kenyataan bahwa saya memerlukan properti virtual jika semantik tidak memerlukannya, jadi, saya hanya membuat properti virtual jika diperlukan. Ketika Anda menentukan bahwa NH tidak boleh menggunakan proksi dinamis, Anda tidak memerlukan alat peraga virtual. - person Frederik Gheysels; 29.12.2009
comment
@Frederik - Jadi apakah saya benar jika mengatakan bahwa Anda yakin suatu kelas adalah persistensi yang bodoh jika tidak memiliki 'referensi' ke kerangka persistensi tertentu, bahkan jika kelas tersebut memiliki perubahan desain signifikan yang dipengaruhi oleh kebutuhan untuk bekerja dengan kerangka kerja tertentu (mis. konstruktor default wajib, anggota virtual untuk pemuatan lambat, Equals/GetHashCode yang ditumbangkan untuk kesetaraan identitas)? Bagaimana jika kerangka lain memerlukan penggunaan Equals/GetHashCode yang berbeda (misalnya untuk kesetaraan semua anggota) sehingga objek Anda tidak dapat berfungsi seperti yang ditulis untuk NHibernate; apakah itu masih kegigihan yang bodoh? - person Greg Beech; 30.12.2009
comment
Bagi saya, NH tidak peduli dengan kegigihan, karena NH tidak mengharuskan anggota Anda menjadi virtual (Anda hanya harus hidup dengan 'kerugian' karena tidak memiliki proxy dinamis, tapi saya menghargai semantik lebih tinggi daripada peningkatan kinerja yang Anda dapatkan dengan dyn. proxy). Selain itu, konstruktor default wajib memang merupakan argumen yang dapat Anda gunakan bahwa NH bukan PI, tetapi Anda dapat menyiasatinya dengan menyediakan konstruktor default pribadi (atau dilindungi). Dibandingkan dengan apa yang dibutuhkan oleh kerangka kerja persitensi lainnya, menurut saya NH cukup bodoh ya. - person Frederik Gheysels; 30.12.2009

Saya setuju dengan definisi Anda:

Oleh karena itu, apakah masuk akal untuk mengatakan bahwa "ketidaktahuan persistensi" benar ketika objek memfasilitasi penggunaan kerangka persistensi, tetapi tidak menjalankan logika persistensi itu sendiri?

Kode (sebagai lawan dari atribut) di kelas Anda tidak memiliki fitur yang intrinsik terhadap persistensi. Konstruktor default mungkin diperlukan untuk persistensi, tetapi tidak memiliki kode yang benar-benar melakukan persistensi. Lapisan persistensi dapat diubah secara signifikan, database yang berbeda dapat digunakan dan logika bisnis tidak akan berubah.

person djna    schedule 29.12.2009
comment
@djna - Saya telah memperbarui definisi saya untuk membuatnya lebih jelas bahwa saya percaya kelas yang dihiasi dengan anotasi khusus kerangka kerja akan tetap dianggap mengabaikan persistensi, karena saya menyadari membaca tanggapan Anda bahwa itu mungkin tidak jelas. Sepertinya Anda masih setuju dengan definisi itu karena Anda hanya mempertimbangkan kode yang dapat dieksekusi, bukan metadata? - person Greg Beech; 29.12.2009
comment
Saya setuju, dengan asumsi bahwa kita dapat menjalankan kode tanpa mengganggu metadata. - person djna; 29.12.2009

Meskipun mungkin ada kendala-kendala kecil tertentu yang diperlukan oleh kerangka ketidaktahuan-persistensi, namun ketidaktahuan-persistensi tetap ada.

Meskipun sebuah kelas dalam model domain Anda (yang secara transparan disimpan dengan NHibernate) harus memiliki konstruktor tanpa argumen sehingga dapat dibangun "secara dinamis", kelas tersebut tidak diharuskan memiliki kelas dasar tertentu yang ditentukan oleh kerangka kerja dan juga tidak diharuskan memiliki kelas dasar tertentu. atau mengganti metode tertentu yang ditentukan kerangka kerja.

person yfeldblum    schedule 29.12.2009
comment
@Justice - Sepertinya Anda baru saja menyatakan kembali pertanyaan saya. Bagaimana Anda melihat pembatasan dalam struktur dan desain suatu objek untuk memfasilitasi penggunaan kerangka kerja secara konseptual berbeda dengan penggunaan anotasi untuk memfasilitasi penggunaan kerangka kerja? - person Greg Beech; 29.12.2009
comment
Batasan yang diberlakukan oleh ORM yang mengabaikan persistensi seperti NHibernate tidak lebih dari batasan yang diberlakukan oleh serialisasi ditambah pemrograman berorientasi aspek (di mana kami memperlakukan persistensi hanya sebagai aspek lain yang menggunakan serialisasi). - person yfeldblum; 29.12.2009
comment
@Justice - Saya tidak jelas apakah Anda mengatakan itu secara konseptual berbeda dengan, katakanlah, serialisasi runtime yang memerlukan atribut [Serializable] atau serialisasi kontrak data yang memerlukan atribut [DataContract]? Ini juga merupakan batasan yang memfasilitasi jenis kerangka serialisasi. - person Greg Beech; 29.12.2009
comment
Baik [Serializable] maupun [DataContract] tidak memungkinkan mekanisme serialisasi umum berfungsi. Itu adalah kelas-kelas tertentu dari kerangka tertentu. Kelas yang memiliki konstruktor tanpa argumen karena serialisasi sama sekali memerlukan konstruktor tanpa argumen masih bisa mengabaikan serialisasi. Namun kelas yang memiliki atribut [Serializable] tidak lagi mengabaikan serialisasi, dan kelas juga tidak mengimplementasikan ISerializable. - person yfeldblum; 29.12.2009
comment
@Justice - [Serializable] persis memfasilitasi mekanisme serialisasi umum; ini tidak lebih dari sebuah konvensi untuk menunjukkan bahwa Anda mengizinkan serialisasi kelas. Anda akan melihat kerangka .NET berisi implementasi formatter berbeda yang menggunakan atribut ini (dua biner dan satu XML). Bagi saya, ini bukanlah perubahan pada perilaku kelas dibandingkan menambahkan konstruktor karena ini adalah metadata, bukan kode yang dapat dieksekusi. - person Greg Beech; 30.12.2009
comment
(Selain itu, serialisasi sama sekali tidak memerlukan konstruktor tanpa argumen. Anda dapat memanggil FormatterServices.GetUninitializedObject dari rakitan yang sepenuhnya tepercaya, persis seperti yang dilakukan kelas IFormatter. Oleh karena itu, memiliki konstruktor default untuk serialisasi tujuan saja setidaknya pada tingkat tertentu merupakan pengakuan akan adanya beberapa jenis serialisasi yang memerlukannya, karena tidak semua melakukannya, dan dengan demikian kelas tidak dapat dikatakan benar-benar bodoh serialisasi, IMHO.) - person Greg Beech; 30.12.2009

Menurut pendapat saya, "ketidaktahuan kegigihan" adalah properti model Anda (model domain, model bisnis, atau apa pun sebutannya). Model ini tidak mengetahui persistensi karena mengambil instance dari entitas yang dikandungnya melalui abstraksi (terkadang disebut sebagai repositori). Abstraksi ini dapat diimplementasikan dengan menggunakan ORM secara langsung, namun seperti yang Anda nyatakan sendiri, hal ini terkadang menambah persyaratan pada objek yang secara alami tidak termasuk dalam model Anda. Oleh karena itu saya tidak akan mengatakan bahwa model yang mematuhi beberapa persyaratan ORM tertentu adalah 100% persistensi bodoh.

person Klaus Byskov Pedersen    schedule 29.12.2009
comment
Saya tidak setuju sepenuhnya. Anda dapat memiliki kelas domain yang diambil melalui abstraksi seperti repositori, tapi itu bukan PI. Ada kemungkinan bahwa kerangka persistensi yang Anda gunakan misalnya, mengharuskan kelas domain Anda mewarisi dari beberapa kelas dasar yang telah ditentukan oleh kerangka persistensi. - person Frederik Gheysels; 29.12.2009

Anda dapat mengimplementasikan ketidaktahuan persistensi menggunakan kelas untuk domain atau aplikasi Anda dan kelas POCO dalam persistensi, ketika Anda akan mempertahankan objek domain, petakan ke dalam kelas persistensi Anda dan gunakan objek persistensi untuk menyimpannya dengan nhibernate atau kerangka kerja lainnya

kelas domain Anda harus mengabaikan bagaimana informasi tersebut disimpan, jadi Anda tidak boleh menyertakan aturan kerangka kerja persistensi seperti (konstruktor kosong, properti virtual, dll.)

aturan kerangka persistensi ini bisa ada di kelas persistensi Anda.

person Miguel Caravantes    schedule 04.07.2018