Saya punya metode yang seharusnya mengembalikan objek jika ditemukan.
Jika tidak ditemukan, haruskah saya:
- kembali nol
- lempar pengecualian
- lain
exception
error-handling
null
Robert
sumber
sumber
Jawaban:
Jika Anda selalu berharap untuk menemukan nilai, maka lempar pengecualian jika nilai itu hilang. Pengecualian akan berarti bahwa ada masalah.
Jika nilainya dapat hilang atau ada dan keduanya valid untuk logika aplikasi, maka kembalikan nol.
Lebih penting: Apa yang Anda lakukan di tempat lain dalam kode? Konsistensi penting.
sumber
GetPersonById(25)
akan melempar jika orang itu telah dihapus, tetapiGetPeopleByHairColor("red")
akan mengembalikan hasil kosong. Jadi, saya pikir parameter mengatakan sesuatu tentang harapan.Hanya melempar pengecualian jika ini benar-benar kesalahan. Jika perilaku yang diharapkan untuk objek tidak ada, kembalikan null.
Kalau tidak, itu adalah masalah preferensi.
sumber
Sebagai aturan umum, jika metode harus selalu mengembalikan objek, maka pergi dengan pengecualian. Jika Anda mengantisipasi null sesekali dan ingin menanganinya dengan cara tertentu, ikuti nol tersebut.
Apa pun yang Anda lakukan, saya sangat menyarankan terhadap opsi ketiga: Mengembalikan string yang mengatakan "WTF".
sumber
Jika nol tidak pernah menunjukkan kesalahan maka kembalilah nol.
Jika nol selalu merupakan kesalahan maka lemparkan pengecualian.
Jika nol terkadang merupakan pengecualian maka kode dua rutinitas. Satu rutin melempar pengecualian dan yang lainnya adalah rutin uji boolean yang mengembalikan objek dalam parameter output dan rutin mengembalikan false jika objek tidak ditemukan.
Sulit untuk menyalahgunakan rutinitas Coba. Sangat mudah untuk lupa untuk memeriksa null.
Jadi ketika nol adalah kesalahan yang baru saja Anda tulis
Ketika nol bukan kesalahan, Anda bisa mengkodekan sesuatu seperti
sumber
find
danfindOrFail
dari LaravelTryFindObject
metode ini? Tuples tampaknya lebih merupakan paradigma malas untuk programmer yang tidak ingin meluangkan waktu untuk mendefinisikan objek yang merangkum beberapa nilai. Itu pada dasarnya semua tuple pada intinya lagian.Saya hanya ingin merekapitulasi opsi yang disebutkan sebelumnya, memasukkan beberapa opsi baru ke:
Atau Anda dapat menggabungkan opsi ini:
Berikan beberapa versi rajin Anda yang rajin, sehingga penelepon dapat memutuskan ke mana harus pergi. Dalam kebanyakan kasus, hanya yang pertama memiliki implementasi algoritma pencarian, dan yang lainnya hanya membungkus yang pertama:
Bahkan jika Anda memilih untuk menyediakan hanya satu implementasi, Anda mungkin ingin menggunakan konvensi penamaan seperti itu untuk memperjelas kontrak Anda, dan itu membantu Anda jika Anda pernah memutuskan untuk menambahkan implementasi lain juga.
Anda tidak boleh menggunakannya secara berlebihan, tetapi mungkin bermanfaat, terutama ketika menulis Kelas pembantu yang akan Anda gunakan dalam ratusan aplikasi yang berbeda dengan banyak konvensi penanganan kesalahan yang berbeda.
sumber
Expected<T> findObject(String)
manaExpected<T>
memiliki fungsiorNull()
,orThrow()
,orSupplied(Supplier<T> supplier)
,orDefault(T default)
. Ini abstrak pengambilan data dari penanganan kesalahanGunakan pola objek nol atau lempar pengecualian.
sumber
Person somePerson = personRepository.find("does-not-exist");
Mari kita asumsikan metode ini mengembalikan objek null untuk IDdoes-not-exist
. Untuk apa perilaku yang benarsomePerson.getAge()
? Saat ini, saya belum yakin pola objek nol adalah solusi yang tepat untuk pencarian entitas.Konsisten dengan API yang Anda gunakan.
sumber
Keuntungan melempar pengecualian:
Untuk penjelasan lebih lanjut dengan contoh, lihat: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
sumber
itu tergantung apakah bahasa dan kode Anda dipromosikan: LBYL (lihat sebelum Anda melompat) atau EAFP (lebih mudah untuk meminta maaf daripada izin)
LBYL mengatakan Anda harus memeriksa nilai-nilai (jadi kembalikan nol)
EAFP mengatakan untuk hanya mencoba operasi dan melihat apakah gagal (membuang pengecualian)
meskipun saya setuju dengan di atas .. pengecualian harus digunakan untuk kondisi luar biasa / kesalahan, dan mengembalikan nol adalah yang terbaik saat menggunakan cek.
EAFP vs. LBYL dalam Python:
http://mail.python.org/pipermail/python-list/2003-May/2051818.html ( Arsip Web )
sumber
Tanyakan kepada diri sendiri: "apakah ini merupakan kasus luar biasa bahwa objek tidak ditemukan"? Jika diharapkan terjadi dalam program normal program Anda, Anda mungkin tidak boleh mengajukan pengecualian (karena itu bukan perilaku yang luar biasa).
Versi singkat: gunakan pengecualian untuk menangani perilaku luar biasa, bukan untuk menangani aliran kontrol normal dalam program Anda.
-Alan.
sumber
Pengecualian terkait dengan Desain berdasarkan Kontrak.
Antarmuka suatu objek sebenarnya merupakan kontrak antara dua objek, pemanggil harus memenuhi kontrak atau penerima mungkin saja gagal dengan pengecualian. Ada dua kontrak yang mungkin
1) semua input metode ini valid, dalam hal ini Anda harus mengembalikan nol ketika objek tidak ditemukan.
2) hanya beberapa input yang valid, yaitu yang menghasilkan objek yang ditemukan. Dalam hal ini Anda HARUS menawarkan metode kedua yang memungkinkan penelepon untuk menentukan apakah inputnya akan benar. Sebagai contoh
JIKA dan HANYA JIKA Anda memberikan kedua metode kontrak ke-2, Anda diizinkan untuk melemparkan pengecualian tidak ada yang ditemukan!
sumber
Saya lebih suka mengembalikan nol, dan mengandalkan penelepon untuk menanganinya dengan tepat. Pengecualian (karena tidak ada kata yang lebih baik) adalah jika saya benar-benar 'yakin' metode ini akan mengembalikan objek. Dalam hal itu kegagalan adalah hal yang harus dan harus dilemparkan.
sumber
Bergantung pada apa artinya benda itu tidak ditemukan.
Jika keadaan normal, maka kembalikan nol. Ini hanya sesuatu yang mungkin terjadi sesekali, dan penelepon harus memeriksanya.
Jika itu adalah kesalahan, lalu melempar pengecualian, penelepon harus memutuskan apa yang harus dilakukan dengan kondisi kesalahan objek yang hilang.
Pada akhirnya keduanya akan berfungsi, meskipun kebanyakan orang umumnya menganggap itu praktik yang baik untuk hanya menggunakan Pengecualian ketika sesuatu, yah, Luar Biasa telah terjadi.
sumber
Berikut beberapa saran lagi.
Jika mengembalikan koleksi, hindari pengembalian nol, kembalikan koleksi kosong yang membuat penghitungan lebih mudah untuk ditangani tanpa cek nol terlebih dahulu.
Beberapa .NET API menggunakan pola parameter thrownOnError yang memberikan pemanggil pilihan apakah itu benar-benar situasi yang luar biasa atau tidak jika objek tidak ditemukan. Type.GetType adalah contoh dari ini. Pola umum lainnya dengan BCL adalah pola TryGet di mana boolean dikembalikan dan nilai dilewatkan melalui parameter output.
Anda juga bisa mempertimbangkan pola Objek Null dalam beberapa keadaan yang bisa menjadi default atau versi tanpa perilaku. Kuncinya adalah menghindari cek nol di seluruh basis kode. Lihat di sini untuk informasi lebih lanjut http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
sumber
Dalam beberapa fungsi saya menambahkan parameter:
Benar berarti melempar, salah berarti mengembalikan beberapa nilai pengembalian kesalahan. Dengan cara ini, siapa pun yang menggunakan fungsi ini memiliki kedua opsi. Defaultnya harus benar, untuk kepentingan mereka yang lupa tentang penanganan kesalahan.
sumber
Kembalikan nol alih-alih melempar pengecualian dan jelas mendokumentasikan kemungkinan nilai pengembalian nol dalam dokumentasi API. Jika kode panggilan tidak menghormati API dan memeriksa kasus nol, kemungkinan besar akan menghasilkan semacam "pengecualian penunjuk nol" pula :)
Dalam C ++, saya dapat memikirkan 3 rasa berbeda dalam mengatur metode yang menemukan objek.
Opsi A
Kembalikan nol ketika suatu objek tidak dapat ditemukan. Bagus dan sederhana. Saya akan memilih yang ini. Pendekatan alternatif di bawah ini adalah untuk orang-orang yang tidak membenci out-params.
Opsi B
Berikan referensi ke variabel yang akan menerima objek. Metode ini membuat pengecualian ketika suatu objek tidak dapat ditemukan. Konvensi ini mungkin lebih cocok jika itu tidak benar-benar diharapkan untuk suatu objek tidak ditemukan - maka Anda melemparkan pengecualian untuk menandakan bahwa itu adalah kasus yang tidak terduga.
Opsi C
Metode mengembalikan false ketika suatu objek tidak dapat ditemukan. Keuntungan opsi over ini A adalah Anda dapat memeriksa kasus kesalahan dalam satu langkah yang jelas:
sumber
hanya merujuk pada kasus di mana null tidak dianggap sebagai perilaku luar biasa saya pasti untuk metode coba, jelas, tidak perlu "membaca buku" atau "melihat sebelum Anda melompat" seperti yang dikatakan di sini
pada dasarnya:
dan ini berarti bahwa kode pengguna juga akan jelas
sumber
Jika penting untuk kode klien untuk mengetahui perbedaan antara ditemukan dan tidak ditemukan dan ini seharusnya menjadi perilaku rutin, maka yang terbaik adalah mengembalikan nol. Kode klien kemudian dapat memutuskan apa yang harus dilakukan.
sumber
Secara umum itu harus mengembalikan nol. Kode yang memanggil metode harus memutuskan apakah akan melempar pengecualian atau mencoba sesuatu yang lain.
sumber
Atau kembalikan Opsi
Opsi pada dasarnya adalah kelas kontainer yang memaksa klien untuk menangani kasing. Scala memiliki konsep ini, lihat API-nya.
Kemudian Anda memiliki metode seperti T getOrElse (T valueIfNull) pada objek ini yang dapat mengembalikan objek yang ditemukan, atau allternative yang ditentukan klien.
sumber
Lebih suka mengembalikan nol -
Jika penelepon menggunakannya tanpa memeriksa, pengecualian terjadi di sana.
Jika penelepon tidak benar-benar menggunakannya, jangan mengenakan pajak pada a
try
/catch
blocksumber
Sayangnya JDK tidak konsisten, jika Anda mencoba mengakses kunci yang tidak ada dalam bundel sumber daya, Anda tidak menemukan pengecualian dan ketika Anda meminta nilai dari peta Anda mendapatkan nol jika itu tidak ada. Jadi saya akan mengubah jawaban pemenang menjadi yang berikut, jika nilai yang ditemukan bisa nol, maka naikkan pengecualian ketika tidak ditemukan, jika tidak kembalikan nol. Jadi ikuti aturan dengan satu pengecualian, jika Anda perlu tahu mengapa nilai tidak ditemukan maka selalu naikkan pengecualian, atau ..
sumber
Selama itu seharusnya mengembalikan referensi ke objek, mengembalikan NULL harus baik.
Namun, jika itu mengembalikan seluruh hal yang berdarah (seperti di C ++ jika Anda melakukannya: 'return bla;' daripada 'return & bla;' (atau 'bla' adalah pointer), maka Anda tidak dapat mengembalikan NULL, karena itu bukan tipe 'objek'. Dalam hal itu, melemparkan pengecualian, atau mengembalikan objek kosong yang tidak memiliki kumpulan flag sukses adalah bagaimana saya akan mendekati masalah.
sumber
Jangan berpikir ada orang yang menyebutkan overhead dalam penanganan pengecualian - membutuhkan sumber daya tambahan untuk memuat dan memproses pengecualian sehingga kecuali itu adalah aplikasi yang benar-benar membunuh atau memproses acara berhenti (maju akan menyebabkan lebih banyak kerugian daripada kebaikan) Saya akan memilih untuk melewatkan kembali nilai lingkungan panggilan bisa menafsirkan sesuai keinginan.
sumber
Saya setuju dengan apa yang tampaknya menjadi konsensus di sini (mengembalikan nol jika "tidak ditemukan" adalah hasil yang normal, atau melemparkan pengecualian jika semantik situasi mengharuskan objek selalu ditemukan).
Namun, ada kemungkinan ketiga yang mungkin masuk akal tergantung pada situasi khusus Anda. Metode Anda dapat mengembalikan objek default dalam kondisi "tidak ditemukan", yang memungkinkan kode panggilan diyakinkan bahwa ia akan selalu menerima objek yang valid tanpa perlu pengecekan nol atau penangkapan pengecualian.
sumber
Kembalikan nol, pengecualian persis seperti itu: sesuatu yang dilakukan kode Anda yang tidak diharapkan.
sumber
Pengecualian harus luar biasa . Kembalikan null jika valid untuk mengembalikan nol .
sumber
Jika metode mengembalikan koleksi, lalu mengembalikan koleksi kosong (seperti dikatakan di atas). Tapi tolong jangan Collections.EMPTY_LIST atau semacamnya! (dalam hal Jawa)
Jika metode ini mengambil satu objek, maka Anda memiliki beberapa opsi.
Hati-hati, jika Anda memutuskan untuk mengembalikan nol. Jika Anda bukan satu-satunya programmer dalam proyek, Anda akan mendapatkan NullPointerExceptions (di Jawa atau apa pun dalam Bahasa lain) saat dijalankan! Jadi jangan mengembalikan nol yang tidak dicentang pada waktu kompilasi.
sumber
null
. Lihat jawaban terpilih untuk lebih banyak.Jika Anda menggunakan perpustakaan atau kelas lain yang melempar pengecualian, Anda harus memikirkannya kembali. Berikut ini sebuah contoh. Example2.java seperti perpustakaan dan Example.java menggunakan objek itu. Main.java adalah contoh untuk menangani Pengecualian ini. Anda harus menunjukkan pesan yang bermakna dan (jika perlu) menumpuk jejak ke pengguna di sisi panggilan.
Main.java
Contoh.java
Example2.java
sumber
Itu sangat tergantung pada apakah Anda berharap untuk menemukan objek, atau tidak. Jika Anda mengikuti aliran pemikiran bahwa pengecualian harus digunakan untuk menunjukkan sesuatu, well, err, pengecualian telah terjadi kemudian:
Jika tidak, kembalikan nol.
sumber