Saya agak tidak setuju dengan pengembang yang lebih berpengalaman tentang masalah ini, dan bertanya-tanya apa pendapat orang lain tentang hal itu; lingkungan kita adalah Java, EJB 3, layanan, dll.
Kode yang saya tulis memanggil layanan untuk mendapatkan sesuatu dan untuk membuat sesuatu. Masalah yang saya temui adalah bahwa saya mendapat pengecualian null pointer yang tidak masuk akal. Misalnya, ketika saya meminta layanan untuk membuat objek, saya mendapatkan null kembali; ketika saya mencoba mencari objek dengan ID valid yang diketahui, saya mendapatkan null kembali. Saya menghabiskan beberapa waktu untuk mencari tahu apa yang salah dalam kode saya; karena saya kurang berpengalaman, saya biasanya berasumsi saya telah melakukan sesuatu yang salah, tetapi ternyata alasan pengembalian nol adalah keamanan. Jika prinsipal pengguna menggunakan layanan saya tidak memiliki izin yang tepat untuk layanan target, maka itu hanya mengembalikan nol. Sebagian besar layanan lain di sini juga tidak didokumentasikan dengan baik, jadi sepertinya ini hanya sesuatu yang harus Anda ketahui.
Ini agak membingungkan karena pengembang menulis kode yang berinteraksi dengan layanan. Akan jauh lebih masuk akal bagi saya jika layanan mencabut pengecualian yang akan memberi tahu saya bahwa pengguna tidak memiliki izin yang tepat untuk memuat hal ini atau untuk membuat hal itu; Saya kemudian akan segera tahu mengapa layanan saya tidak berfungsi seperti yang diharapkan.
Pengembang yang lebih berpengalaman yang menulis layanan berpendapat bahwa meminta data bukan kondisi kesalahan, dan bahwa pengecualian hanya boleh dilemparkan dalam kondisi kesalahan, bukan ketika pengguna tidak memiliki akses ke data. Data ini sering dicari dalam GUI, dan bagi pengguna tanpa izin yang tepat, hal-hal ini "tidak ada". Jadi, singkatnya: bertanya itu tidak salah, maka tidak terkecuali. Dapatkan metode mengembalikan nol karena bagi pengguna itu hal-hal "tidak ada". Buat metode mengembalikan nol ketika pengguna tidak diizinkan untuk membuat hal itu.
Apakah ini normal dan / atau praktik yang baik? Saya lebih suka menggunakan pengecualian karena saya merasa lebih mudah untuk mengetahui apa yang terjadi. Jadi saya akan misalnya juga lebih suka melempar NotFoundException jika Anda meminta objek dengan ID yang tidak valid, daripada mengembalikan nol.
sumber
Jawaban:
Meminta sesuatu mungkin bukan kesalahan, tetapi tidak memiliki izin untuk sesuatu yang Anda minta pasti semacam kesalahan. Pengecualian adalah cara alternatif untuk melaporkan kondisi luar biasa, yang akan digunakan alih-alih nilai pengembalian khusus (seperti
null
, yang, seperti yang Anda tulis, sama sekali tidak membantu jika ada> 1 kemungkinan alasan mengapa segala sesuatunya menjadi serba salah (bahkan jika ada tepat 1 kemungkinan alasan sekarang, mungkin ada 2 alasan yang mungkin di versi berikutnya, jadi menggunakannull
sebagai nilai pengembalian yang menunjukkan kegagalan akan mengecat diri Anda sendiri ke sudut)). Jika layanan tidak melaporkan mengapa tidak melakukan apa yang Anda minta, maka itu pasti desain yang buruk.Apakah akan menggunakan nilai pengembalian khusus (misalnya bilangan bulat negatif berguna untuk fungsi yang biasanya mengembalikan bilangan bulat negatif), pengecualian, penangan kesalahan global atau pencatat dll, adalah detail implementasi pada akhirnya. Pilihannya tergantung pada bahasa, situasi, konvensi, dan juga masalah selera. Titik utama adalah bahwa harus ada beberapa cara langsung mencari tahu mengapa sesuatu tidak bekerja. Kalau tidak, satu-satunya pilihan Anda adalah mencari sampah dengan opsi yang berbeda dan apa pun untuk mengetahui apa yang berkorelasi dengan perilaku kotak hitam, dan itu membuang-buang waktu.
String.substring()
melemparIndexOutOfBoundsException
jika indeks di luar batas. Saya tidak bisa memikirkan keuntungan untuk kembalinull
sebagai gantinya, meskipun - secara filosofis - orang dapat berargumen bahwa aString
tidak mengandung apa pun di luar batasnya, jadi itunull
akan menjadi nilai pengembalian logis saat itu. Menjadi logis-filosofis dan praktis adalah dua binatang yang berbeda.sumber
substring
mengembalikan referensi nol. IMHO, harus ada dua fungsi terpisah - satu di antaranya berjanji untuk mengembalikan jumlah karakter yang diminta atau melemparkan pengecualian, dan satu di antaranya mengembalikan sebanyak mungkin. Setiap metode akan jauh lebih unggul dari yang lain dalam beberapa konteks.Turun ke apa kontrak itu. Jika kontrak Anda mengatakan Anda dapat meminta sesuatu yang tidak ada, itu harus mengatakan apa yang terjadi (null, atau null object).
Di sisi lain, jika kontrak Anda mengatakan Anda harus memanggil metode yang berbeda terlebih dahulu (
DoesSomethingExist()
) dan kemudian memanggilGet
metode tersebut, maka kontrak Anda mungkin mengatakan bahwa Anda hanya bisa mendapatkan hal-hal yang memang ada, dan melemparkan pengecualian jika tidak. Pesan pengecualian bisa mengatakan sesuatu seperti, "Pastikan untuk meneleponDoesSomethingExist()
dulu" yang merupakan pesan kesalahan yang berguna.sumber
findAllThings
metode, maka saya akan mengatakan pantas untuk mengembalikan daftar kosong atau subset jika ada beberapa atau semua hal yang tidak boleh Anda lihat. Dengan cara yang sama saya mungkin hanya menulis posting di blog untuk diedit milik pengguna saat ini. Tetapi jika pengguna itu kemudian mencoba mengubah url dan mengedit posting yang berbeda ...Tidak ada jawaban tunggal untuk semua pertanyaan. Apakah akan menggunakan pengecualian atau mengembalikan null tergantung pada situasinya.
Alih-alih melihat ini murni dari sudut pandang dogmatis, lihatlah antarmuka sebagai antarmuka pengguna . Antarmuka pengguna harus dapat digunakan . Jadi, terlepas dari pendapat Anda sendiri tentang cara "benar" untuk melakukan sesuatu, pilih metode yang paling dapat digunakan dari perspektif seseorang yang menggunakan antarmuka Anda.
Jika penelepon perlu tahu mengapa suatu objek tidak dikembalikan, pengecualian sesuai. Namun, jika konsep umum adalah "jika Anda tidak memiliki izin, itu tidak ada", nol dapat diterima.
Khususnya dalam kasus Anda, saya akan mengatakan nulls sangat dapat diterima untuk mencari item jika penelepon pertama kali diminta untuk masuk atau terhubung ke server. Saat itulah Anda akan diberitahu bahwa Anda memiliki atau tidak memiliki izin. Setelah Anda melewati gerbang masuk akal bahwa ketika Anda mencari sesuatu yang Anda tidak memiliki izin untuk melihat (atau bahkan tahu itu ada), Anda harus mendapatkan nol.
Di sisi lain, jika Anda tidak memiliki koneksi awal atau langkah masuk, pengecualian masuk akal. Jika penelepon mengetahui ada item dan mereka tidak mendapatkannya kembali, API tidak membantu untuk hanya mengembalikan nol.
Namun untuk membuat item, itu cerita yang berbeda. Mungkin ada banyak alasan untuk itu gagal - tidak ada izin, parameter buruk, server kehabisan memori, dll. Jika pengembang diberi nol untuk semua kondisi tersebut, mereka tidak memiliki cara untuk menentukan tindakan yang tepat .
Jadi, untuk menjawab pertanyaan, tanyakan pada diri Anda apa solusi yang paling bermanfaat dari sudut pandang seseorang yang menggunakan layanan ini. Bisa jadi cara Anda menggunakannya tidak lazim, dan untuk kasus yang paling umum, nol adalah jawaban yang tepat.
Jadi, jangan terlibat dalam perang agama karena ini, putuskan apa yang tepat untuk masalah khusus ini.
sumber
Saya pasti berpikir itu adalah desain yang buruk . Null-pointer bukan jawaban yang valid untuk saya dan itu bisa rumit untuk dikelola.
Jika pengguna mencoba menghubungkan layanan tanpa kredensial yang tepat, saya harus menjawab dengan jawaban yang jelas dan ringkas. Jawabannya bisa berupa pengecualian atau objek khusus tetapi tidak nol.
Anda harus meninggalkan jawaban nol ketika tautan jaringan rusak atau kerusakan kritis tak terduga lainnya.
Selain itu, waktu yang Anda habiskan untuk memahami mengapa Anda mendapat nol adalah argumen yang kuat. Setiap potongan kode harus mudah dipahami dan digunakan. Tidak memiliki nilai nol.
sumber
Mengingat desain perangkat lunak yang baik dalam pikiran, Anda harus berpikir tentang kehidupan proyek Anda.
Dengan kembali
null
, seperti yang telah dikatakan, Anda tidak memberikan informasi apa pun kepada klien. Lihatlah apa yang terjadi pada Anda, pada awalnya Anda tidak menyadari di mana masalahnya. Apalagi, jika tidak ada dokumentasi yang diberikan, ini berantakan.Dengan melemparkan pengecualian, Anda dapat mengetahui apa yang salah. Anda bahkan dapat menyesuaikan teks yang ditampilkan agar lebih spesifik jika Anda mau.
Di sisi lain, dengan kembali
null
Anda membuat klien menyelidiki apa yang sedang terjadi.Selanjutnya, Anda menyadari bahwa ada masalah karena Anda mendapat tempat lain
NullPointerException
. Sekarang bayangkan Anda tidak menyimpan kembalinya fungsi itu ... Anda akan dipaksa untuk mengelilingi setiap panggilan ke fungsi itu dengan sebuahif else
blok ...Dari sudut pandang saya, kembali
null
adalah praktik yang buruk.sumber
Dari sudut pandang saya, ini tidak masuk akal.
Permintaan data tanpa izin harus menghasilkan pengecualian, karena ini merupakan hasil yang tidak terduga - untuk tidak mendapatkan hasil - tanpa akses yang tepat.
Analogi : Responsecode untuk
GET
tanpa otorisasi bukan200 ok
tanpa data, sebenarnya401 Unauthorized
.sumber
Mengembalikan nol tidak bagus. Ini tidak memberi tahu Anda apa-apa. Sebagai contoh, jika suatu aplikasi mencoba mencari sesuatu dan jawabannya adalah nol untuk kedua masalah keamanan dan jika item tersebut tidak ada, lalu bagaimana Anda membedakan antara keduanya?
Respons yang berarti dapat memungkinkan aplikasi untuk membuat pilihan logis tentang apa yang harus dilakukan selanjutnya atau bagaimana menyelesaikan masalah.
sumber
Jika akar penyebabnya adalah pengguna yang tidak diautentikasi maka saya lebih suka respons HTTP 401 yang keras mungkin dengan mengarahkan ulang ke halaman pesan-cantik (dan pemberitahuan kepada seseorang yang peduli). Penyebab terkait otorisasi lebih banyak kasus per kasus; ada argumen untuk mengembalikan kesalahan HTTP (403, katakanlah) dan argumen untuk mengembalikan kode / pesan khusus yang terbentuk dengan baik dalam respons layanan.
Pengecualian hanya boleh digunakan dalam situasi khusus dan berarti ada sesuatu yang salah. Saya tidak setuju bahwa mereka harus kelebihan beban berarti "tidak diizinkan". (Hal yang sama berlaku untuk nilai pengembalian nol: Saya tidak setuju bahwa itu harus digunakan untuk berarti "tidak diizinkan".)
sumber
Untuk berperan sebagai advokat setan, saya akan berusaha mengambil sisi mengembalikan null.
Menurut pendapat saya hanya ada satu situasi di mana respons semacam ini hampir dapat diterima dan itu adalah, seperti dalam kasus ini, ketika keamanan terlibat.
Sangat mudah untuk secara tidak sengaja memberikan rincian sistem Anda yang tidak perlu diketahui orang yang tidak berwenang. Ini harus dihindari.
Ambil, misalnya, nama pengguna dan pemeriksa kata sandi. Mengembalikan kesalahan "Nama pengguna tidak ditemukan" dan kesalahan "Kata sandi salah" karena kode kesalahan yang terpisah jelas akan membuka Anda terhadap masalah keamanan serius karena seseorang pertama-tama dapat mencari nama pengguna yang valid dan kemudian mencari kata sandi. Mengembalikan "nama pengguna / kata sandi" generik akan menjadi opsi yang lebih baik.
Jadi, dalam kasus khusus ini saya akan mengatakan bahwa hampir tidak masalah untuk kembali
null
tetapi saya setuju, akan sangat tidak menyenangkan untuk bekerja dengannya.sumber
null
adalah jawaban yang paling tidak membantu. Hampir semua hal lain berpotensi digunakan untuk menemukan sesuatu tentang sistem. Alasan OP mengeluh adalah karena tidak hanyanull
mengembalikan tidak menjelaskan apa-apa itu bahkan tidak membantu. Itu adalah tujuan yang disengaja ... untuk tidak mengatakan apa - apa dan tidak membantu. Misi tercapai dalam pandangan saya.Saya pikir return null tidak ramah, ketika klien memanggil metode ini dan mengembalikan null, klien tidak tahu apa yang terjadi dan mengapa itu mengembalikan null. Jadi kita harus membuang eksekusi yang masuk akal dan memberikan dokumentasi untuk mendeskripsikan eksekusi ini.
sumber