Apa yang salah dalam mengembalikan hashtable dari metode publik dan kapan masuk akal untuk melakukannya?

9

Apa masalah desain dalam mengembalikan hashtable dari metode publik saat Anda ingin mengembalikan beberapa item alih-alih membuat kelas dan mengembalikan objek itu?

Jika memang ada masalah maka dalam keadaan apa masuk akal untuk melakukannya?

Bagaimana jawaban untuk pertanyaan ini berubah tergantung pada apakah bahasanya dinamis atau tidak?

Sunting: Ini untuk memperjelas bahwa kunci akan konstan dan merupakan bagian dari kode, bukan data. Sesuatu yang biasanya kita buat kelasnya. Pertanyaannya adalah mengapa salah menggunakan hashtable sebagai gantinya jika membuat kelas memang tampaknya merupakan pilihan yang tepat.

Muhammad Hasan Khan
sumber

Jawaban:

11

Gunakan kelas yang didefinisikan lebih baik sebagai jenis pengembalian daripada hashtable yang menampung jumlah nilai acak sebagai pasangan nama / nilai.

  1. Poin pertama dan terpenting adalah - Maintainability. Dengan melihat kodenya, seorang programmer baru tidak akan pernah bisa mengatakan apa saja nilai yang dikembalikan metode tersebut. Jika orang baru tidak memahami ini dengan melihat kode, kode tersebut tidak akan berguna dan rentan terhadap kesalahan setiap kali seseorang akan menambahkan lebih banyak kunci / nilai pada data itu atau meningkatkan aplikasi.

  2. Metode adalah kontrak antara penelepon dan layanan. Hal terpenting dalam suatu metode adalah input dan output mereka. Input dan output ini harus mudah dibaca dan dimengerti serta didokumentasikan sendiri. Jika Anda menggunakan kelas Orang sebagai nilai kembali yang memiliki nama depan, nama belakang, usia - Ini adalah dokumentasi sendiri. Jika Anda menghasilkan Javadoc untuk ini, pengguna dapat menavigasi antar kelas untuk memahami ini dengan lebih baik. Jika Anda menggunakan hashtable, Anda harus menjelaskannya di komentar yang tidak akan dibaca atau diperbarui ketika ada perubahan.

  3. Anda tidak dapat menggunakan obat generik seperti HashMap<String,String>dalam kasus jika Anda ingin menambahkan nomor (katakan usia) ke pernyataan pengembalian. Jika Anda tidak menggunakan obat generik, maka Anda harus melakukan bolak-balik antara objek ke tipe aktual. Anda dapat menyimpan ini jika Anda menggunakan pengetikan dinamis.

  4. Juga ada lebih banyak peluang kegagalan runtime daripada menangkap masalah dalam waktu kompilasi. mis. jika seseorang menghapus entri dari hashmap dan salah satu penelepon lama mengharapkan entri, klien gagal selama runtime. Itu selalu lebih baik untuk menangkap masalah ini dalam waktu kompilasi.

  5. Akan sulit untuk mengembalikan tipe yang tidak dapat diubah jika Anda ingin menggunakan hashmap sebagai tipe kembali dan seterusnya. Tetapi jika Anda menggunakan pengguna yang menentukan tipe Anda sendiri, Anda dapat mengontrol ini.

Ini akan tergoda untuk menggunakan hashmap sebagai tipe pengembalian karena Anda dapat menghindari membuat beberapa kelas di awal tetapi akan menjadi mimpi buruk untuk mempertahankan kode di masa depan. Pergi berorientasi objek !!!!

java_mouse
sumber
1
Anda sepertinya telah memahami pertanyaan dengan benar. Terima kasih.
Muhammad Hasan Khan
8

Salah satu masalah adalah bahwa dalam banyak kasus, kunci untuk tabel hash adalah string. Jadi konsumen metode harus tahu sebelumnya kunci mana yang digunakan untuk mengekstraksi data. Ini akan memberikan potensi kesalahan karena kesalahan ejaan saat mengakses data.

Kelemahan lain adalah refactorability. Jika Anda kemudian memutuskan untuk mengubah nama anggota, Anda kemudian memiliki banyak string sihir yang juga perlu diubah. Jauh lebih mudah untuk mengganti nama anggota kelas menggunakan alat refactoring yang disediakan oleh sebagian besar IDE yang bagus. Dengan tabel hash Anda mungkin harus melakukan operasi find / replace di semua file sumber yang mungkin bermasalah.

Terakhir, Anda akan kehilangan waktu kompilasi untuk memeriksa akses anggota - baik dari segi nama dan jenis. Yang terakhir ini tidak menjadi masalah jika tabel hash Anda hanya berisi satu jenis obejct, tetapi jika berisi banyak (bahkan dalam rantai hierarki yang sama) Anda benar-benar ingin memanfaatkan sistem tipe bahasa Anda dan mendapatkan waktu kompilasi memeriksa di sana. Di sebagian besar IDE, Anda akan memiliki beberapa fitur intellisense / autocomplete - ini bekerja dengan melihat pada sistem tipe, tetapi mereka tidak akan dapat membantu Anda dengan kunci tabel hash.

Adapun saat-saat ketika akan tepat untuk mengembalikan tabel hash (atau kumpulan pasangan nilai kunci lainnya), Anda akan menggunakan ini ketika nilai dan kunci tidak diketahui pada waktu kompilasi. Misalnya, jika Anda memiliki metode yang mem-parsing string kueri dan mengembalikan kunci & nilai yang sesuai, tabel hash akan menjadi pilihan yang baik. Dalam hal ini Anda juga ingin berpikir tentang mengembalikan semacam tabel hash yang tidak berubah atau hanya baca.

Sunting - Sebagian besar poin yang diangkat dalam jawaban ini berhenti berlaku ketika Anda berbicara tentang bahasa dinamis :)

MattDavey
sumber
Bagaimana jika bahasanya dinamis?
Muhammad Hasan Khan
Saya bukan ahli dalam bahasa dinamis sehingga orang lain mungkin bisa memberikan jawaban yang lebih baik untuk itu. Tetapi saya tahu bahwa bahasa dinamis tidak melakukan kompilasi pengecekan tipe waktu. Tetapi dalam kasus itu mengembalikan objek dan mengembalikan tabel hash tidak begitu berbeda ..
MattDavey
3
@ Khan Khan: Dalam hal ini mungkin sebenarnya tidak ada perbedaan antara hashtable dan instance kelas. Misalnya, dalam Javascript semua objek adalah hashtable, dan object.property persis sama dengan objek ['properti']
Michael Borgwardt
"Dengan tabel hash Anda mungkin harus melakukan operasi find / replace di semua file sumber yang bisa bermasalah." Hanya jika Anda telah memilih kunci yang buruk dan tidak pernah mencoba memfaktorkan yang standar sehingga ditetapkan di satu tempat ...
Donal Fellows
7

Argumen paling penting yang menentang hal ini adalah Anda terlalu banyak mengungkapkan informasi kepada konsumen. Kode pengkonsumsi hanya perlu tahu bahwa itu semacam koleksi nilai-kunci (kamus); apakah itu diterapkan sebagai hashmap, daftar asosiasi, trie, atau apa pun, relatif tidak menarik. Jadi cara yang tepat adalah kembali dengan antarmuka yang sesuai ( IDictionary, atau apa pun bahasa pilihan Anda menggunakan) bukan dengan tipe yang sebenarnya.

Semua ini dengan asumsi bahwa Anda benar-benar membutuhkan kamus untuk mewakili data Anda, yaitu, data Anda terdiri dari pasangan kunci / nilai, di mana kunci tersebut unik di antara dataset, dan tidak dapat diperbaiki pada waktu kompilasi. Jika Anda memiliki kunci yang diketahui sebelumnya, Anda harus membuat jenis yang tepat (atau beberapa, sesuai kebutuhan) untuk data Anda. Itu tergantung pada apakah Anda menganggap kunci itu sendiri sebagai bagian dari data, atau bagian dari kode.

EDIT :

Untuk memperjelas, saya menggunakan kamus istilah yang berarti tipe paling umum dari struktur data nilai kunci di sini; Maksud saya bukan implementasi khusus bahasa seperti Python dictatau .NET Dictionary.

tammmer
sumber
1
+1 untuk "Ini tergantung pada apakah Anda menganggap kunci itu sendiri sebagai bagian dari data, atau bagian dari kode." - Itu cara yang bagus untuk menjelaskannya. Misalnya, tidak yakin seberapa universal istilah 'kamus' dan bukan 'peta'.
MattDavey
Mengembalikan kamus tidak dimaksudkan. kunci adalah bagian dari kode, bukan data.
Muhammad Hasan Khan
Pertanyaan sebenarnya adalah alasan di balik 'Anda harus membuat tipe yang tepat'. Pertanyaan mengapa?
Muhammad Hasan Khan
2

Satu pertanyaan yang akan saya tanyakan pada diri saya adalah "apakah kunci berubah dalam kamus ini?" Jika mereka konstan maka Anda harus mengembalikan objek atau struktur data lain yang sesuai. Jika mereka dinamis maka Anda mungkin ingin mengembalikan semacam struktur gaya kamus. Akhirnya, jika ada beberapa kunci yang akan menjadi konstan dan beberapa set kunci dinamis yang tidak diketahui, Anda mungkin ingin mengembalikan struktur data hybrid termasuk beberapa nilai tetap dan semacam kamus untuk overflow.

Wyatt Barnett
sumber
Memang saran Anda benar tetapi pertanyaannya adalah apa yang salah dengan memilih menggunakan hashtable ketika kelas adalah pilihan yang lebih baik.
Muhammad Hasan Khan
Itu bukan / atau; sebuah kelas dapat dengan mudah berisi kamus jika Anda membutuhkannya.
Wyatt Barnett