Bahasa Pemrograman Gagal Membedakan Antara Data dan Objek, Menyebabkan Pilihan Desain yang Buruk

Tim Komunitas BigGo
Bahasa Pemrograman Gagal Membedakan Antara Data dan Objek, Menyebabkan Pilihan Desain yang Buruk

Perdebatan yang berkembang dalam komunitas pemrograman berpusat pada cacat mendasar dalam cara bahasa pemrograman modern menangani berbagai jenis informasi. Diskusi ini menyoroti bagaimana bahasa-bahasa tersebut memaksa pengembang ke dalam kompromi yang canggung ketika merepresentasikan data sederhana versus objek kompleks dengan perilaku.

Masalah inti berasal dari bahasa yang memperlakukan segala sesuatu dengan cara yang sama, baik itu angka sederhana yang tidak pernah berubah atau komponen sistem kompleks yang mempertahankan state dari waktu ke waktu. Pendekatan satu ukuran untuk semua ini menciptakan kompleksitas yang tidak perlu dan mengarah pada keputusan arsitektural yang buruk di seluruh industri perangkat lunak.

Kisah Dua Paradigma Pemrograman

Komunitas pemrograman telah mengidentifikasi dua pendekatan berbeda yang cenderung disukai oleh bahasa-bahasa pemrograman. Bahasa berorientasi objek seperti Java mendorong segala sesuatu ke dalam objek, bahkan nilai sederhana seperti angka. Ini menciptakan overhead dan kompleksitas di mana seharusnya tidak ada. Di sisi lain, bahasa fungsional seperti Haskell unggul dalam menangani data murni tetapi kesulitan ketika Anda membutuhkan komponen stateful yang mempertahankan identitas dari waktu ke waktu.

Diskusi komunitas mengungkapkan bahwa C# telah membuat kemajuan signifikan dalam mengatasi perpecahan ini. Tidak seperti Java , C# membedakan antara tipe nilai (struct) untuk data sederhana dan tipe referensi (class) untuk objek dengan identitas. Pilihan desain ini, yang ada sejak versi pertama bahasa, memungkinkan pengembang untuk membuat keputusan sadar tentang bagaimana data mereka harus berperilaku.

Pendekatan Bahasa Pemrograman terhadap Perbedaan Data/Objek

  • C: Pemisahan yang jelas dengan tipe nilai (structs) vs tipe referensi (classes) sejak versi 1
  • Java: Pendekatan segala-sesuatu-sebagai-objek, perlahan menambahkan tipe nilai melalui Project Valhalla
  • Haskell: Dukungan data yang kuat dengan tipe aljabar, kemampuan seperti objek yang terbatas
  • Scala: Kelas case berusaha menjembatani kesenjangan antara data dan objek
  • Erlang/Elixir: Fondasi data immutable yang solid dengan simulasi objek berbasis proses
  • Rust: Berusaha menyediakan keamanan dan performa dengan kompleksitas yang meningkat

Dampak Dunia Nyata pada Arsitektur Sistem

Kebingungan antara data dan objek telah mempengaruhi tren teknologi utama dengan cara yang tidak terduga. Gerakan NoSQL mendapat daya tarik sebagian karena database tradisional kesulitan dengan struktur data seperti pohon, memaksa pengembang untuk mencari solusi alternatif dari batasan relasional. Demikian pula, REST API menjadi populer karena memungkinkan sistem untuk bertukar data aktual sebagai JSON , daripada berurusan dengan kompleksitas pendekatan berorientasi objek SOAP .

Saya tidak menyalahkan siapa pun karena sedikit kegembiraan yang tidak rasional setelah dibebaskan dari batasan itu. Sangat membebaskan untuk menyimpan data, bukan?

Komunitas menunjukkan bahwa banyak masalah arsitektur layanan berasal dari kebingungan mendasar ini. Pengembang sering membuat layanan yang hanya mengacak-acak data alih-alih memberikan perilaku yang bermakna, yang mengarah pada anti-pattern persisten dari layanan CRUD yang telah coba dihilangkan oleh konsultan selama lebih dari satu dekade.

Pertimbangan Kinerja dan Praktis

Perdebatan meluas ke implikasi kinerja juga. Struktur data yang tidak dapat diubah, yang disukai oleh advokat pemrograman fungsional, memberikan jaminan keamanan dan bekerja dengan baik dalam lingkungan multi-threaded. Namun, mereka datang dengan biaya kinerja dibandingkan dengan mutasi di tempat yang digunakan dalam skenario kinerja tinggi seperti sistem perdagangan dan mesin game.

Bahasa seperti Erlang dan Elixir menunjukkan manfaat dari fondasi yang solid dengan data yang tidak dapat diubah, tetapi mereka tidak memiliki sistem tipe statis yang dianggap penting oleh banyak pengembang untuk proyek skala besar. Sementara itu, bahasa yang lebih baru seperti Rust berusaha memberikan keamanan dan kinerja, meskipun dengan peningkatan kompleksitas yang harus dikuasai pengembang.

Perbandingan Karakteristik Data vs Objek

Aspek Data Objek
Kesetaraan Berbasis nilai: setiap 1 sama dengan 1 Berbasis identitas: 1 ini ≠ 1 itu
Penyalinan Salin dengan bebas, hanya bytes Serialisasi menciptakan identitas baru
Kemutabilan Tidak dapat diubah secara alami Biasanya dapat diubah untuk manajemen state
Internal Terbuka, sesuai dengan skema Dienkapsulasi dengan akses terkontrol
Ekstensibilitas Varian tetap, fungsi tak terbatas Operasi tetap, varian dapat diperluas

Jalan ke Depan

Komunitas pemrograman semakin menyadari bahwa desain bahasa masa depan harus secara eksplisit mendukung kedua paradigma daripada memaksa segala sesuatu ke dalam satu model. Pengembang membutuhkan alat yang memungkinkan mereka secara sadar memilih antara merepresentasikan sesuatu sebagai data murni atau sebagai objek dengan perilaku dan identitas.

Beberapa bahasa berkembang ke arah ini. Java perlahan menambahkan tipe nilai melalui Project Valhalla , sementara case class Scala menyediakan jalan tengah antara data murni dan objek penuh. Namun, solusi ini sering terasa seperti tambalan pada sistem yang ada daripada prinsip desain fundamental.

Diskusi menunjukkan bahwa desain bahasa pemrograman yang lebih baik dapat mencegah banyak masalah arsitektural dengan membuat pilihan data-versus-objek eksplisit dan mendukung kedua pola dengan sama baik. Ini akan membantu pengembang membuat keputusan desain yang lebih sadar dan menghindari kebingungan yang saat ini mengganggu arsitektur perangkat lunak.

Referensi: Data, objects, and how we're railroaded into poor design