Saya sering menulis fungsi semacam ini di kedua format, dan saya bertanya-tanya apakah satu format lebih disukai daripada yang lain, dan mengapa.
public void SomeFunction(bool someCondition)
{
if (someCondition)
{
// Do Something
}
}
atau
public void SomeFunction(bool someCondition)
{
if (!someCondition)
return;
// Do Something
}
Saya biasanya kode dengan yang pertama karena itu adalah cara otak saya bekerja saat coding, meskipun saya pikir saya lebih suka yang ke-2 karena menangani penanganan kesalahan segera dan saya merasa lebih mudah untuk membaca
Jawaban:
Saya lebih suka gaya kedua. Dapatkan kasus yang tidak valid terlebih dahulu, baik hanya keluar atau menaikkan pengecualian yang sesuai, masukkan garis kosong di sana, lalu tambahkan tubuh "nyata" metode ini. Saya merasa lebih mudah dibaca.
sumber
Jelas yang terakhir. Yang pertama tidak terlihat buruk sekarang, tetapi ketika Anda mendapatkan kode yang lebih kompleks, saya tidak bisa membayangkan ada orang yang berpikir seperti ini:
lebih mudah dibaca daripada
Saya sepenuhnya mengakui bahwa saya tidak pernah mengerti keuntungan dari titik keluar tunggal.
sumber
return value;
membantu!?! Maka seseorang harus berburu setengah lusinvalue = ...
, dengan kerugian bahwa Anda tidak pernah yakin bahwa nilai tidak akan berubah antara tugas ini dan pengembalian akhir. Setidaknya pengembalian segera jelas bahwa tidak ada yang akan mengubah hasilnya lagi.Itu tergantung - Secara umum saya tidak akan keluar dari cara saya untuk mencoba dan memindahkan banyak kode untuk keluar dari fungsi awal - kompiler umumnya akan mengurus itu untuk saya. Walaupun begitu, jika ada beberapa parameter dasar di bagian atas yang saya butuhkan dan tidak dapat dilanjutkan, saya akan breakout lebih awal. Demikian juga, jika suatu kondisi menghasilkan
if
blok raksasa dalam fungsi saya akan menerobosnya lebih awal sebagai akibatnya juga.Meskipun demikian, jika suatu fungsi memerlukan beberapa data saat dipanggil, saya biasanya akan melempar pengecualian (lihat contoh) sebagai lawan dari hanya kembali.
sumber
Saya lebih suka pengembalian awal.
Jika Anda memiliki satu titik masuk dan satu titik keluar maka Anda harus selalu melacak seluruh kode di kepala Anda sampai ke titik keluar (Anda tidak pernah tahu jika ada bagian kode lainnya di bawah melakukan sesuatu yang lain pada hasilnya, sehingga Anda harus melacaknya sampai ada). Anda melakukan itu tanpa masalah cabang mana yang menentukan hasil akhir. Ini sulit diikuti.
Dengan satu entri dan beberapa ada, Anda kembali ketika Anda memiliki hasil Anda dan tidak repot-repot melacak semuanya untuk melihat bahwa tidak ada yang melakukan hal lain untuk itu (karena tidak akan ada hal lain sejak Anda kembali). Ini seperti memiliki tubuh metode yang dipecah menjadi lebih banyak langkah, yang setiap langkah dengan kemungkinan untuk mengembalikan hasilnya atau membiarkan langkah berikutnya mencoba peruntungannya.
sumber
Dalam pemrograman C di mana Anda harus membersihkan secara manual ada banyak yang bisa dikatakan untuk pengembalian satu poin. Sekalipun saat ini tidak perlu untuk membersihkan sesuatu, seseorang mungkin mengedit fungsi Anda, mengalokasikan sesuatu dan perlu membersihkannya sebelum kembali. Jika itu terjadi, itu akan menjadi pekerjaan mimpi buruk melihat semua pernyataan kembali.
Dalam pemrograman C ++ Anda memiliki destruktor dan bahkan sekarang pelindung ruang-keluar. Semua ini harus ada di sini untuk memastikan kode tersebut aman dari awal, sehingga kode dijaga dengan baik terhadap keluar awal dan oleh karena itu melakukannya tidak memiliki kelemahan logis dan murni masalah gaya.
Saya tidak cukup berpengetahuan tentang Java, apakah "akhirnya" kode blok akan dipanggil dan apakah finalizers dapat menangani situasi yang diperlukan untuk memastikan sesuatu terjadi.
C # Saya tentu tidak bisa menjawab.
D-bahasa memberi Anda penjaga ruang keluar yang tepat dan karena itu dipersiapkan dengan baik untuk keluar awal dan oleh karena itu tidak boleh menghadirkan masalah selain gaya.
Fungsi tentu saja tidak boleh terlalu lama di tempat pertama, dan jika Anda memiliki pernyataan beralih besar kode Anda mungkin juga sangat diperhitungkan.
sumber
goto
dan, mungkin, pengembalian dua poin. Contoh (pemformatan kode tidak dimungkinkan dalam komentar):foo() { init(); if (bad) goto err; bar(); if (bad) goto err; baz(); return 0; err: cleanup(); return 1; }
Pengembalian awal untuk-menang. Mereka bisa terlihat jelek, tetapi jauh lebih jelek daripada
if
pembungkus besar , terutama jika ada beberapa kondisi untuk diperiksa.sumber
Saya menggunakan keduanya.
Jika
DoSomething
3-5 baris kode maka kode tersebut terlihat cantik menggunakan metode pemformatan pertama.Tetapi jika memiliki lebih banyak baris dari itu, maka saya lebih suka format kedua. Saya tidak suka ketika kurung buka dan tutup tidak di layar yang sama.
sumber
Alasan klasik untuk single-entry-single-exit adalah bahwa jika semantik formal menjadi sangat buruk (alasan yang sama GOTO dianggap berbahaya).
Dengan kata lain, lebih mudah untuk mempertimbangkan kapan perangkat lunak Anda akan keluar dari rutin jika Anda hanya memiliki 1 pengembalian. Yang juga merupakan argumen terhadap pengecualian.
Biasanya saya meminimalkan pendekatan pengembalian awal.
sumber
Secara pribadi, saya lebih suka melakukan pemeriksaan kondisi lulus / gagal di awal. Itu memungkinkan saya untuk mengelompokkan sebagian besar kegagalan paling umum di bagian atas fungsi dengan sisa logika untuk diikuti.
sumber
Tergantung.
Pengembalian lebih awal jika ada beberapa kondisi jalan buntu yang jelas untuk memeriksa segera yang akan membuat menjalankan seluruh fungsi menjadi sia-sia. *
Atur Retval + pengembalian tunggal jika fungsinya lebih kompleks dan bisa memiliki beberapa titik keluar jika tidak (masalah keterbacaan).
* Ini sering dapat menunjukkan masalah desain. Jika Anda menemukan bahwa banyak metode Anda perlu memeriksa beberapa keadaan eksternal / paramater atau semacamnya sebelum menjalankan sisa kode, itu mungkin sesuatu yang harus ditangani oleh penelepon.
sumber
Fred
jendela sudahFred
, dan pengaturan nama kontrol ke keadaan sekarang akan memaksa redraw (yang, meskipun berpotensi berguna dalam beberapa kasus, akan menjadi menjengkelkan dalam satu di tangan), itu akan sangat masuk akal untuk memiliki metode set-nama awal-keluar jika nama lama dan baru cocok.Gunakan If
Dalam buku Don Knuth tentang GOTO, saya membacanya memberikan alasan untuk selalu memiliki kondisi yang paling mungkin didahulukan dalam pernyataan if. Di bawah asumsi bahwa ini masih merupakan ide yang masuk akal (dan bukan satu-satunya pertimbangan murni untuk kecepatan era). Saya akan mengatakan pengembalian awal bukan praktik pemrograman yang baik, terutama mengingat fakta bahwa mereka lebih sering daripada tidak digunakan untuk penanganan kesalahan, kecuali kode Anda lebih cenderung gagal daripada tidak gagal :-)
Jika Anda mengikuti saran di atas, Anda harus meletakkan pengembalian itu di bagian bawah fungsi, dan Anda mungkin bahkan tidak menyebutnya pengembalian di sana, cukup atur kode kesalahan dan kembalikan dua baris karenanya. Dengan demikian mencapai 1 entri 1 keluar ideal.
Delphi Tertentu ...
Saya berpikir bahwa ini adalah praktik pemrograman yang baik untuk programmer Delphi, meskipun saya tidak punya bukti. Pra-D2009, kami tidak memiliki cara atom untuk mengembalikan nilai, kami memiliki
exit;
danresult := foo;
atau kami bisa saja melemparkan pengecualian.Jika Anda harus menggantinya
untuk
Anda mungkin bosan melihat bahwa di atas setiap fungsi Anda dan lebih suka
dan hindari
exit
sama sekali.sumber
if true then Exit(foo);
sering saya gunakan teknik ini untuk pertama menginisialisasiresult
kenil
atauFALSE
masing-masing, kemudian memeriksa semua kondisi kesalahan dan hanyaExit;
jika salah satu terpenuhi. Kasus suksesresult
kemudian (biasanya) diatur di suatu tempat di akhir metode.Saya setuju dengan pernyataan berikut:
Diambil dari pertanyaan ini di stackoverflow .
sumber
Saya menggunakan pengembalian awal hampir secara eksklusif hari ini, ke ekstrem. Saya menulis ini
sebagai
tapi itu benar-benar tidak masalah. Jika Anda memiliki lebih dari satu atau dua tingkat sarang dalam fungsi Anda, mereka perlu rusak.
sumber
Saya lebih suka menulis:
sumber
DoSomeFunctionIfSomeCondition
?Seperti Anda, saya biasanya menulis yang pertama, tetapi lebih suka yang terakhir. Jika saya memiliki banyak pemeriksaan bersarang saya biasanya refactor ke metode kedua.
Saya tidak suka bagaimana penanganan kesalahan dipindahkan dari cek.
Saya lebih memilih ini:
sumber
Kondisi di atas disebut "prasyarat". Dengan meletakkan
if(!precond) return;
, Anda secara visual mendaftar semua prasyarat.Menggunakan blok "jika-lain" yang besar dapat meningkatkan indent overhead (saya lupa kutipan tentang indentasi 3-level).
sumber
Saya lebih suka menyimpan jika pernyataan kecil.
Jadi, memilih di antara:
dan
Saya akan memilih apa yang Anda gambarkan sebagai "pengembalian awal".
Pikiran Anda, saya tidak peduli tentang pengembalian awal atau apa pun, saya hanya ingin menyederhanakan kode, mempersingkat badan jika pernyataan, dll.
Bersarang jika dan untuk dan sementara itu mengerikan , hindari mereka di semua biaya.
sumber
Seperti yang orang lain katakan, itu tergantung. Untuk sedikit fungsi yang mengembalikan nilai, saya dapat mengkode pengembalian lebih awal. Tetapi untuk fungsi yang cukup besar, saya ingin selalu mendapat tempat dalam kode di mana saya tahu saya bisa meletakkan sesuatu yang akan dieksekusi sebelum kembali.
sumber
Saya berlatih gagal-cepat di tingkat fungsi. Itu membuat kode konsisten dan bersih (bagi saya dan mereka yang pernah bekerja dengan saya). Karena itu saya selalu kembali lebih awal.
Untuk beberapa kondisi yang sering diperiksa, Anda dapat menerapkan aspek-aspek untuk pemeriksaan tersebut jika Anda menggunakan AOP.
sumber