Saya terkadang menemukan kode yang mirip dengan contoh berikut (apa fungsi ini tidak persis di luar lingkup pertanyaan ini):
function doSomething(value) {
if (check1(value)) {
return -1;
}
else if (check2(value)) {
return value;
}
else {
return false;
}
}
Seperti yang Anda lihat, if
, else if
dan else
pernyataan yang digunakan dalam hubungannya dengan return
pernyataan. Ini tampaknya cukup intuitif untuk pengamat biasa, tapi saya pikir akan lebih elegan (dari perspektif pengembang perangkat lunak) untuk menghapus else
-s dan menyederhanakan kode seperti ini:
function doSomething(value) {
if (check1(value)) {
return -1;
}
if (check2(value)) {
return value;
}
return false;
}
Ini masuk akal, karena segala sesuatu yang mengikuti return
pernyataan (dalam lingkup yang sama) tidak akan pernah dieksekusi, membuat kode di atas secara semantik sama dengan contoh pertama.
Manakah di atas yang lebih cocok dengan praktik pengkodean yang baik? Apakah ada kekurangan pada kedua metode sehubungan dengan keterbacaan kode?
Sunting: Saran rangkap telah dibuat dengan pertanyaan ini disediakan sebagai referensi. Saya percaya pertanyaan saya menyentuh topik yang berbeda, karena saya tidak bertanya tentang menghindari pernyataan rangkap seperti yang disajikan dalam pertanyaan lain. Kedua pertanyaan berusaha mengurangi pengulangan, meskipun dengan cara yang sedikit berbeda.
else
lebih kecil, masalah yang lebih besar adalah Anda jelas mengembalikan dua tipe data dari satu fungsi, yang membuat API dari fungsi tersebut tidak dapat diprediksi.-1
adalah angka,false
adalah boolean, danvalue
tidak ditentukan di sini sehingga bisa berupa semua jenis objek.value
sebenarnya adalah bilangan bulat. Jika itu bisa apa saja maka itu bahkan lebih buruk.Jawaban:
Saya suka yang tanpa
else
dan inilah alasannya:Karena melakukan itu tidak merusak apa pun yang tidak seharusnya.
Benci saling ketergantungan dalam semua bentuk itu (termasuk penamaan fungsi
check2()
). Isolasi semua yang bisa diisolasi. Terkadang Anda membutuhkanelse
tetapi saya tidak melihatnya di sini.sumber
if
blok} //else
untuk memperjelas, ketika membaca kode, bahwa satu-satunya eksekusi yang dimaksudkan setelahif
blok kode adalah jika kondisi dalamif
pernyataan itu salah. Tanpa sesuatu seperti ini, terutama jika kode di dalamif
blok tumbuh menjadi lebih kompleks, mungkin tidak jelas bagi siapa pun yang menjaga kode bahwa maksudnya adalah untuk tidak pernah mengeksekusi melewatiif
blok ketikaif
kondisinya benar.if
untuk memperjelas bahwa bagian kode ini selesai dan struktur selesai. Untuk melakukan ini saya melakukan apa yang belum saya lakukan di sini (karena saya tidak ingin mengalihkan perhatian dari poin utama OP dengan membuat perubahan lain). Saya melakukan hal paling sederhana yang dapat saya lakukan untuk mencapai semua itu tanpa mengganggu. Saya menambahkan baris kosong.Saya pikir itu tergantung pada semantik kode. Jika ketiga kasus Anda saling bergantung, nyatakan secara eksplisit. Ini meningkatkan keterbacaan kode dan membuatnya lebih mudah dipahami oleh orang lain. Contoh:
Di sini Anda jelas tergantung pada nilai
x
dalam ketiga kasus. Jika Anda menghilangkan yang terakhirelse
, ini akan menjadi kurang jelas.Jika kasing Anda tidak saling tergantung satu sama lain, abaikan saja:
Sulit untuk menunjukkan ini dalam contoh sederhana tanpa konteks, tetapi saya harap Anda mengerti maksud saya.
sumber
Saya lebih suka pilihan kedua (terpisah
ifs
tanpaelse if
dan awalreturn
) TAPI yang selama blok kode pendek .Jika blok kode panjang, lebih baik menggunakan
else if
, karena selain itu Anda tidak akan memiliki pemahaman yang jelas tentang beberapa titik keluar kode.Sebagai contoh:
Dalam hal ini, lebih baik digunakan
else if
, simpan kode kembali dalam variabel dan hanya memiliki satu kalimat kembali di akhir.Tetapi sebagai salah satu harus berusaha untuk fungsi menjadi pendek, saya akan mengatakan tetap pendek dan keluar lebih awal seperti dalam cuplikan kode pertama Anda.
sumber
return
berada dalam 3 barisif
sehingga tidak jauh berbedaelse if
bahkan setelah 200 baris kode. The gaya kembali tunggal Anda memperkenalkan sini adalah tradisi c dan bahasa lain yang tidak melaporkan kesalahan dengan pengecualian. Intinya adalah menciptakan satu tempat untuk membersihkan sumber daya. Bahasa pengecualian menggunakanfinally
blok untuk itu. Saya kira ini juga menciptakan tempat untuk meletakkan break point jika debugger Anda tidak akan membiarkan Anda menempatkan satu pada fungsi penutupan kurung kurawal.retVal
sama sekali. Jika Anda dapat dengan aman keluar dari suatu fungsi segera lakukan, tanpa menetapkan nilai aman untuk dikembalikan ke variabel keluar tunggal dari fungsi. Ketika Anda menggunakan titik pengembalian tunggal dalam fungsi yang sangat panjang, saya biasanya tidak mempercayai programmer lain dan akhirnya mencari melalui seluruh fungsi untuk modifikasi lain dari nilai kembali juga. Gagal berpuasa dan kembali lebih awal, antara lain, dua aturan yang saya jalani.Saya menggunakan keduanya dalam keadaan yang berbeda. Dalam pemeriksaan validasi, saya menghilangkan yang lain. Dalam aliran kontrol, saya menggunakan yang lain.
vs.
Kasing pertama berbunyi lebih seperti Anda memeriksa semua prasyarat terlebih dahulu, menyingkirkan semua itu, lalu maju ke kode aktual yang ingin Anda jalankan. Dengan demikian, kode berair yang benar-benar ingin Anda jalankan termasuk dalam ruang lingkup fungsi secara langsung; itulah fungsi sebenarnya.
Kasus kedua berbunyi lebih seperti kedua jalur adalah kode yang valid untuk dijalankan yang sama relevan dengan fungsi seperti yang lain berdasarkan beberapa kondisi. Dengan demikian, mereka termasuk dalam tingkat cakupan yang sama satu sama lain.
sumber
Satu-satunya situasi yang pernah saya lihat benar-benar penting adalah kode seperti ini:
Jelas ada sesuatu yang salah di sini. Masalahnya adalah, tidak jelas apakah
return
harus ditambahkan atauArrays.asList
dihapus. Anda tidak dapat memperbaikinya tanpa pemeriksaan yang lebih dalam terhadap metode terkait. Anda dapat menghindari ambiguitas ini dengan selalu menggunakan blok if-else yang lengkap. Ini:tidak akan dikompilasi (dalam bahasa yang dicentang secara statis) kecuali Anda menambahkan pengembalian eksplisit terlebih dahulu
if
.Beberapa bahasa bahkan tidak mengizinkan gaya pertama. Saya mencoba menggunakannya hanya dalam konteks yang sangat penting atau untuk prasyarat dalam metode panjang:
sumber
Memiliki tiga keluar dari fungsi seperti itu benar-benar membingungkan jika Anda mencoba mengikuti kode dan praktik yang buruk.
Jika Anda memiliki satu titik keluar untuk fungsi tersebut maka elemen yang diperlukan.
Bahkan mari kita melangkah lebih jauh.
Cukup adil Anda bisa berdebat untuk pengembalian awal input validasi tunggal. Hanya menghindari membungkus keseluruhan massal jika logika Anda dalam sebuah if.
sumber
Saya lebih suka menghilangkan pernyataan redundant else. Setiap kali saya melihatnya (dalam review kode atau refactoring) saya bertanya-tanya apakah penulis memahami aliran kontrol dan bahwa mungkin ada bug dalam kode.
Jika penulis percaya pernyataan lain diperlukan dan dengan demikian tidak memahami implikasi aliran kontrol dari pernyataan kembali tentu saja kurangnya pemahaman adalah sumber utama bug, dalam fungsi ini, dan secara umum.
sumber