Mengapa saya tidak membutuhkan ORM dalam bahasa fungsional seperti Scala?

30

Saya ingin tahu apakah saya dapat beralih dari Jawa ke Scala di proyek Spring + Hibernate untuk memanfaatkan beberapa fitur Scala seperti pencocokan pola, Opsi, dan apa yang menurut saya sintaks yang lebih bersih secara umum. Saya telah mencari ORM secara default di ekosistem Scala dan saya menemukan berpikir seperti Aktifkan (tapi kebanyakan saya mencoba mencari apakah Hibernate dapat digunakan dengan Scala). Mencari ini, saya sudah membaca ini di dokumentasi Play tentang JPA + Scala.

Tetapi poin yang paling penting adalah: apakah Anda benar-benar membutuhkan Relationnal to Objects mapper ketika Anda memiliki kekuatan bahasa fungsional? Mungkin tidak. JPA adalah cara yang mudah untuk mengabstraksi kurangnya kekuatan Jawa dalam transformasi data, tetapi rasanya benar-benar salah ketika Anda mulai menggunakannya dari Scala.

Saya tidak memiliki pemahaman yang mendalam tentang bagaimana menggunakan pemrograman fungsional untuk membuat aplikasi lengkap (itu sebabnya saya bermaksud untuk menggunakan Scala sehingga saya dapat memahami ini secara bertahap, karena menggabungkan OO + Fungsional), jadi saya tidak tahu mengapa saya tidak memerlukan ORM dengan bahasa fungsional dan apa yang akan menjadi pendekatan fungsional untuk mengatasi ketekunan model domain.

Pendekatan DDD untuk logika bisnis masih masuk akal dengan Scala, bukan?

gabrielgiussi
sumber
3
Ini pertanyaan berbasis opini. Scala tidak sepenuhnya fungsional, ini juga merupakan bahasa OO, jadi itu akan menjelaskan mengapa Anda masih ingin menggunakan alat ORM. Untuk pemetaan DB, lihat misalnya: Slick , SORM , Anorm .
Jesper
Saya tidak mencari pendapat, saya meminta sesuatu dengan pemahaman mendalam tentang paradigma fungsional apa cara untuk mencapai kegigihan. Saya tahu bahwa Scala adalah hibrida dan saya ingin menggunakan bagian OO untuk DDD. Jadi Anda mengatakan bahwa jika saya mengambil pendekatan DDD bahkan dengan Scala, ORM adalah cara untuk pergi?
gabrielgiussi
Dalam bahasa fungsional Anda terutama berurusan dengan nilai-nilai yang tidak memiliki identitas seperti halnya objek. Karenanya Anda tidak perlu pelacakan perubahan yang merupakan salah satu pekerjaan utama ORM.
Lee
2
Anda mungkin menyukai ceramah ini: Dari Fungsional ke Reaktif - Pola dalam Pemodelan Domain
Jesper
5
Anda tidak memerlukan ORM dalam bahasa utama apa pun .
GrandmasterB

Jawaban:

30

Nah, satu hal yang penting untuk dilakukan setiap kali kita berdiskusi seperti ini adalah dengan jelas membedakan antara obyek pemetaan relasional ("ORM") dan lapisan abstraksi basis data . ORM adalah sejenis lapisan abstraksi basis data, tetapi tidak semua lapisan abstraksi basis data adalah ORM. Salah satu alat yang baik untuk belajar memahami hal ini adalah pustaka SQLAlchemy populer Python , yang menyebut dirinya sebagai "toolkit SQL dan Object Relational Mapper" (huruf tebal saya), dengan gagasan bahwa ini adalah hal yang berbeda. Ketika mereka meletakkannya di halaman fitur utama mereka :

Tidak diperlukan ORM

SQLAlchemy terdiri dari dua komponen berbeda, yang dikenal sebagai Core dan ORM . Core sendiri merupakan toolkit abstraksi SQL berfitur lengkap, memberikan lapisan abstraksi yang halus atas beragam implementasi dan perilaku DBAPI, serta Bahasa Ekspresi SQL yang memungkinkan ekspresi bahasa SQL melalui ekspresi Python generatif. Sistem representasi skema yang dapat memancarkan pernyataan DDL serta mengintrospeksi skema yang ada, dan sistem tipe yang memungkinkan pemetaan tipe Python ke tipe basis data, melengkapi sistem. Object Relational Mapper kemudian merupakan paket opsional yang dibangun di atas Core.

Halaman depan menggambarkan ORM seperti ini:

SQLAlchemy paling terkenal dengan objek-relational mapper (ORM), komponen opsional yang menyediakan pola data mapper, di mana kelas-kelas dapat dipetakan ke database secara terbuka, berbagai cara - memungkinkan model objek dan skema database untuk berkembang dalam suatu cara dipisahkan bersih dari awal.

Gagasan kunci ORM adalah mencoba dan menjembatani ketidakcocokan impedansi objek-relasional yang terkenal . Ini berarti mendefinisikan hubungan antara kelas yang ditentukan pengguna ke tabel dalam skema database dan menyediakan operasi "simpan" dan "muat" otomatis untuk kelas aplikasi Anda.

Sebaliknya, lapisan abstraksi database non-ORM cenderung lebih berkomitmen pada model data relasional dan SQL, dan sama sekali tidak berorientasi objek. Jadi alih-alih menampilkan "pemetaan" antara tabel dan kelas dan menyembunyikan skema database dari programmer, mereka cenderung mengekspos database ke programmer tetapi dengan API dan abstraksi yang lebih baik. Misalnya, pembangun kueri SQL memungkinkan Anda untuk menghasilkan kueri SQL kompleks secara terprogram, tanpa manipulasi string, seperti ini ( contoh dari perpustakaan jOOQ untuk Java ):

// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
    create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
          .from(BOOK)
          .join(AUTHOR)
          .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
          .where(BOOK.PUBLISHED_IN.equal(1948))
          .fetch();

Sekarang, kerangka bermain tampaknya tidak 100% sesuai dengan apa yang saya jelaskan , tetapi argumen mereka tampaknya berada di ruang umum ini: bekerja dengan model relasional secara langsung alih-alih menerjemahkannya ke kelas dan kembali dari mereka.

The jOOQ perpustakaan bernilai belajar sebagai tandingan ke ORMs. Mereka juga memiliki beberapa entri blog yang relevan yang patut dibaca:

sakundim
sumber
19

Agak sulit untuk dijelaskan sampai Anda telah melakukan banyak pemrograman fungsional. Dalam pemrograman berorientasi objek, data Anda terjebak di satu objek dan tetap di sana. Objek itu akan diedarkan sedikit, dan dimodifikasi sedikit, tetapi Anda biasanya bekerja secara fundamental dengan "identitas" yang sama selama masa pakai data itu.

ORM umumnya dirancang berdasarkan paradigma itu. Anda mengambil beberapa data dari database, memasukkannya ke dalam objek, berpotensi memodifikasinya banyak, dan ketika Anda selesai, Anda masih memiliki objek yang sama yang dapat Anda tulis kembali ke database.

Pemrograman fungsional berfungsi secara berbeda. Data Anda tidak mempertahankan satu identitas selama masa pakainya. Itu akan terpecah, disalin, dibagikan, dan diubah. Ini semacam mengalir melalui banyak fungsi, kemudian akhirnya akan dipasang kembali ke bentuk output yang Anda butuhkan. Agar API basis data apa pun terasa alami dalam bahasa fungsional, ia harus memperhitungkannya, dan JPA tidak.

Karl Bielefeldt
sumber
1
+1000 Orang yang bersikeras menggunakan Scala seolah-olah itu Java ++ membuat saya takut untuk masa depan bahasa :(
Andres F.
9

Dalam scala masih berguna untuk memetakan tabel database ke objek, dan ada beberapa cara untuk melakukannya.

Salah satu kerangka kerja populer di dunia Scala adalah apik . Ini bukan ORM, karena ia lebih sedikit (yaitu, ia tidak menjemput hubungan tanpa disuruh bergabung secara eksplisit).

Jadi, Anda masih memetakan objek ke baris basis data, tetapi objek Anda tidak berubah, (karenanya tidak ada pembilasan negara) dan Anda secara eksplisit menjalankan kueri menggunakan DSL monadik. Hasilnya adalah Anda mendapatkan banyak bagian "baik" dari ORM tanpa masalah seputar mutabilitas, dan masalah N + 1 yang tidak dapat diprediksi.

Orang harus mencatat bahwa orang-orang mendapatkan sukses besar menggunakan banyak perpustakaan yang lebih tipis, seperti anorm atau JDBC lurus, menggunakan teknik fungsional untuk menjaga kode tetap indah.

Satu pustaka fantastis yang menerapkan teknik fungsional di atas JDBC juga doobie .

Jadi Anda memiliki banyak pilihan untuk akses database, tetapi Hibernate (yang tampaknya merupakan ORM de-facto) bukan salah satu yang terbaik, karena bias terhadap kemampuan berubah-ubah.

triggerNZ
sumber
0

Anda tidak memerlukan ORM bahkan dalam bahasa berorientasi objek.

Pertama, siapa yang mengatakan bahwa data Anda harus disalin secara fisik dari penyimpanan gigih Anda ke objek Anda? Alan Kay , seorang pria di belakang Smalltalk, ingin benda - benda untuk menyingkirkan data . Dia menyarankan bahwa suatu objek hanya dapat memiliki referensi ke beberapa area di mana datanya disimpan.

Kedua - apa cara terbaik untuk mencapainya? Saya sarankan mengidentifikasi objek Anda dengan tanggung jawab mereka , dan tidak memikirkan data yang mereka miliki. Jika Anda pernah mendengar tentang pendekatan kartu CRC, itu digunakan tepat untuk itu.

Dan, akhirnya, kalau-kalau Anda akan kembali ke OO-field, berikut adalah cara untuk mengimplementasikannya .

Zapadlo
sumber