Bos saya terus menyebutkan dengan acuh tak acuh bahwa programmer buruk menggunakan break
dan continue
dalam loop.
Saya menggunakannya sepanjang waktu karena mereka masuk akal; izinkan saya menunjukkan inspirasi kepada Anda:
function verify(object) {
if (object->value < 0) return false;
if (object->value > object->max_value) return false;
if (object->name == "") return false;
...
}
Intinya di sini adalah bahwa pertama fungsi memeriksa bahwa kondisinya benar, kemudian menjalankan fungsionalitas yang sebenarnya. IMO yang sama berlaku dengan loop:
while (primary_condition) {
if (loop_count > 1000) break;
if (time_exect > 3600) break;
if (this->data == "undefined") continue;
if (this->skip == true) continue;
...
}
Saya pikir ini membuatnya lebih mudah untuk dibaca & debug; tapi saya juga tidak melihat sisi negatifnya.
goto
) berguna dalam beberapa kasus.Jawaban:
Ketika digunakan pada awal blok, seperti cek pertama kali dibuat, mereka bertindak seperti prasyarat, jadi itu bagus.
Ketika digunakan di tengah blok, dengan beberapa kode di sekitarnya, mereka bertindak seperti perangkap tersembunyi, jadi itu buruk.
sumber
Anda dapat membaca makalah Donald Knuth's 1974 Program Structured dengan pergi ke Pernyataan , di mana ia membahas berbagai penggunaan
go to
yang secara struktural diinginkan. Mereka termasuk yang setarabreak
dancontinue
pernyataan (banyak penggunaango to
di sana telah dikembangkan menjadi konstruksi yang lebih terbatas). Apakah bos Anda tipe yang menyebut Knuth seorang programmer yang buruk?(Contoh-contoh yang diberikan menarik minat saya. Biasanya,
break
dancontinue
tidak disukai oleh orang-orang yang menyukai satu entri dan satu keluar dari setiap kode, dan orang semacam itu juga mengerutkan dahi pada banyakreturn
pernyataan.)sumber
Break
,Continue
danExit
sebagai alat di kotak alat saya; Saya menggunakannya di mana itu membuat kode lebih mudah diikuti, dan jangan menggunakannya di mana hal itu akan membuat lebih sulit untuk dibaca.Saya tidak percaya mereka jahat. Gagasan bahwa mereka buruk berasal dari masa pemrograman terstruktur. Ini terkait dengan gagasan bahwa suatu fungsi harus memiliki satu titik masuk dan satu titik keluar, yaitu hanya satu
return
per fungsi.Ini masuk akal jika fungsi Anda panjang, dan jika Anda memiliki beberapa loop bersarang. Namun, fungsi Anda harus pendek, dan Anda harus membungkus loop dan tubuhnya menjadi fungsi pendek sendiri. Secara umum, memaksa suatu fungsi untuk memiliki satu titik keluar dapat menghasilkan logika yang sangat berbelit-belit.
Jika fungsi Anda sangat pendek, jika Anda memiliki satu loop, atau paling buruk dua loop bersarang, dan jika tubuh loop sangat pendek, maka sangat jelas apa yang dilakukan oleh a
break
atau acontinue
. Juga jelas apa yang dilakukan banyakreturn
pernyataan.Masalah-masalah ini dibahas dalam "Kode Bersih" oleh Robert C. Martin dan "Refactoring" oleh Martin Fowler.
sumber
CALL P(X, Y, &10)
, dan jika terjadi kesalahan, fungsi tersebut dapat memberikan kontrol ke pernyataan itu, alih-alih kembali ke titik panggilan.Programmer yang buruk berbicara secara absolut (seperti Sith). Pemrogram yang baik menggunakan solusi sejelas mungkin ( semua hal lain dianggap sama ).
Menggunakan break dan melanjutkan sering membuat kode sulit untuk diikuti. Tetapi jika menggantinya membuat kode lebih sulit untuk diikuti, maka itu adalah perubahan yang buruk.
Contoh yang Anda berikan jelas merupakan situasi di mana istirahat dan terus harus diganti dengan sesuatu yang lebih elegan.
sumber
Kebanyakan orang berpikir itu ide yang buruk karena perilakunya tidak mudah diprediksi. Jika Anda membaca kode dan Anda
while(x < 1000){}
menganggap Anda akan menjalankannya sampai x> = 1000 ... Tetapi jika ada jeda di tengah, maka itu tidak berlaku, sehingga Anda tidak dapat benar-benar mempercayai Anda perulangan ...Itu alasan yang sama orang tidak suka GOTO: tentu saja, itu dapat digunakan dengan baik, tetapi juga dapat menyebabkan kode spaghetti yang luar biasa, di mana kode melompat secara acak dari bagian ke bagian.
Bagi saya sendiri, jika saya akan melakukan loop yang rusak pada lebih dari satu kondisi, saya akan lakukan
while(x){}
kemudian beralih X ke false ketika saya perlu untuk keluar. Hasil akhirnya akan sama, dan siapa pun yang membaca kode akan tahu untuk melihat lebih dekat pada hal-hal yang mengubah nilai X.sumber
while(notDone){ }
pendekatan tersebut.break;
denganx=false;
tidak membuat kode Anda lebih jelas. Anda masih harus mencari isi pernyataan itu. Dan jikax=false;
Anda harus memeriksa bahwa itu tidak menekanx=true;
lebih jauh ke bawah.while (x < 1000)
saya menganggap itu akan berjalan 1000 kali". Nah, ada banyak alasan mengapa itu salah, meskipunx
awalnya nol. Misalnya, siapa bilangx
bertambah tepat sekali selama loop, dan tidak pernah dimodifikasi dengan cara lain? Bahkan untuk asumsi Anda sendiri, hanya karena set sesuatux >= 1000
tidak berarti loop akan berakhir - itu dapat diatur kembali dalam kisaran sebelum kondisi diperiksa.Ya Anda dapat [kembali] menulis program tanpa pernyataan break (atau kembali dari tengah loop, yang melakukan hal yang sama). Tetapi Anda mungkin harus memperkenalkan variabel tambahan dan / atau duplikasi kode yang keduanya biasanya membuat program lebih sulit untuk dipahami. Pascal (bahasa pemrograman) sangat buruk terutama untuk programmer pemula karena alasan itu. Atasan Anda pada dasarnya ingin Anda memprogram dalam struktur kontrol Pascal. Jika Linus Torvalds ada di sepatu Anda, dia mungkin akan menunjukkan kepada bos Anda jari tengah!
Ada hasil ilmu komputer yang disebut hierarki struktur kontrol Kosaraju, yang berasal dari tahun 1973 dan yang disebutkan dalam makalah Knuth yang terkenal pada tahun 1974. (Makalah Knuth ini sudah direkomendasikan di atas oleh David Thornley, omong-omong .) Apa yang dibuktikan oleh S. Rao Kosaraju pada tahun 1973 adalah bahwa tidak mungkin untuk menulis ulang semua program yang memiliki multi level level kedalaman n ke dalam program-program dengan kedalaman break kurang dari n tanpa memperkenalkan variabel tambahan. Tetapi katakanlah itu hanya hasil teoretis semata. (Cukup tambahkan beberapa variabel tambahan ?! Tentunya Anda dapat melakukan itu untuk menyenangkan bos Anda ...)
Apa yang jauh lebih penting dari perspektif rekayasa perangkat lunak adalah makalah yang lebih baru, tahun 1995 oleh Eric S. Roberts berjudul Loop Exits and Structured Programming: Membuka Kembali Debat ( http://cs.stanford.edu/people/eroberts/papers/SIGCSE- 1995 / LoopExits.pdf ). Roberts merangkum beberapa studi empiris yang dilakukan oleh orang lain sebelum dia. Sebagai contoh, ketika sekelompok siswa tipe CS101 diminta untuk menulis kode untuk fungsi yang mengimplementasikan pencarian sekuensial dalam array, penulis penelitian mengatakan hal berikut tentang siswa yang menggunakan break / return / goto untuk keluar dari dari loop pencarian berurutan ketika elemen ditemukan:
Roberts juga mengatakan bahwa:
Ya, Anda mungkin lebih berpengalaman daripada siswa CS101, tetapi tanpa menggunakan pernyataan break (atau ekuivalen kembali / kebohongan dari tengah-tengah loop), pada akhirnya Anda akan menulis kode bahwa sementara yang terstruktur dengan baik cukup berbulu dalam hal logika tambahan variabel dan duplikasi kode yang seseorang, mungkin diri Anda sendiri, akan memasukkan bug logika di dalamnya ketika mencoba mengikuti gaya pengkodean bos Anda.
Saya juga akan mengatakan di sini bahwa makalah Roberts jauh lebih mudah diakses oleh programmer rata-rata, jadi bacaan pertama yang lebih baik daripada karya Knuth. Ini juga lebih pendek dan mencakup topik yang lebih sempit. Anda mungkin bahkan dapat merekomendasikannya kepada atasan Anda, bahkan jika dia adalah manajemen dan bukan tipe CS.
sumber
Saya tidak mempertimbangkan menggunakan salah satu dari praktik buruk ini, tetapi menggunakannya terlalu banyak di dalam loop yang sama harus menjamin memikirkan kembali logika yang digunakan dalam loop. Gunakan dengan hemat.
sumber
Contoh yang Anda berikan tidak perlu istirahat atau dilanjutkan:
'Masalah' saya dengan 4 baris dalam contoh Anda adalah bahwa mereka semua berada pada level yang sama tetapi mereka melakukan hal-hal yang berbeda: beberapa istirahat, beberapa melanjutkan ... Anda harus membaca setiap baris.
Dalam pendekatan bertingkat saya, semakin dalam Anda melangkah, semakin 'bermanfaat' kode tersebut.
Tetapi, jika jauh di lubuk hati Anda akan menemukan alasan untuk menghentikan loop (selain kondisi primer), istirahat atau kembali akan menggunakannya. Saya lebih suka menggunakan bendera ekstra yang akan diuji dalam kondisi tingkat atas. Break / return lebih langsung; itu lebih baik menyatakan maksud daripada menetapkan variabel lain.
sumber
<
perbandingan Anda harus<=
sesuai dengan solusi OP"Kejahatan" tergantung pada bagaimana Anda menggunakannya. Saya biasanya menggunakan istirahat dalam looping constructs ONLY ketika itu akan menyelamatkan saya siklus yang tidak dapat disimpan melalui refactoring suatu algoritma. Misalnya, bersepeda melalui koleksi mencari item dengan nilai di properti tertentu yang disetel ke true. Jika yang perlu Anda ketahui adalah bahwa salah satu item memiliki properti ini disetel ke true, setelah Anda mencapai hasil itu, istirahat adalah baik untuk mengakhiri loop dengan tepat.
Jika menggunakan istirahat tidak akan membuat kode secara khusus lebih mudah dibaca, lebih pendek untuk menjalankan atau menyimpan siklus dalam pemrosesan secara signifikan, maka yang terbaik adalah tidak menggunakannya. Saya cenderung memberi kode ke "common denominator terendah" bila mungkin untuk memastikan bahwa siapa pun yang mengikuti saya dapat dengan mudah melihat kode saya dan mencari tahu apa yang terjadi (saya tidak selalu berhasil dalam hal ini). Istirahat mengurangi itu karena mereka memperkenalkan titik masuk / keluar aneh. Disalahgunakan mereka bisa berperilaku sangat mirip dengan pernyataan "goto" yang mendera.
sumber
Sama sekali tidak ... Ya penggunaannya
goto
buruk karena memperburuk struktur program Anda dan juga sangat sulit untuk memahami aliran kontrol.Tetapi penggunaan pernyataan seperti
break
dancontinue
sangat diperlukan hari ini dan tidak dianggap sebagai praktik pemrograman yang buruk sama sekali.Dan juga tidak sulit untuk memahami aliran kontrol dalam penggunaan
break
dancontinue
. Dalam konstruksi sepertiswitch
yangbreak
pernyataan mutlak diperlukan.sumber
Gagasan penting berasal dari kemampuan menganalisis program Anda secara semantik. Jika Anda memiliki satu entri dan satu keluar, matematika yang diperlukan untuk menunjukkan kemungkinan keadaan jauh lebih mudah daripada jika Anda harus mengelola jalur forking.
Sebagian, kesulitan ini mencerminkan kemampuan berpikir secara konseptual tentang kode Anda.
Terus terang, kode kedua Anda tidak jelas. Apa yang sedang dilakukannya? Apakah melanjutkan 'melanjutkan', atau apakah 'selanjutnya' loop? Saya tidak punya ide. Setidaknya contoh pertama Anda jelas.
sumber
Saya akan mengganti potongan kode kedua Anda dengan
bukan karena alasan kesederhanaan - saya benar-benar berpikir ini lebih mudah dibaca dan bagi seseorang untuk memahami apa yang sedang terjadi. Secara umum kondisi loop Anda harus terkandung murni dalam kondisi loop yang tidak berserakan di seluruh tubuh. Namun ada beberapa situasi di mana
break
dancontinue
dapat membantu keterbacaan.break
lebih banyak daripada yangcontinue
bisa saya tambahkan: Dsumber
foreach
loop karena ini hanya akan mengulangi setiap item dalam koleksi. Sebuahfor
loop serupa dalam hal itu seharusnya tidak memiliki titik akhir bersyarat. Jika Anda memang membutuhkan titik akhir bersyarat maka Anda perlu menggunakanwhile
loop.break
maksimum menurut pendapat saya dari loop.Saya tidak setuju dengan atasan Anda. Ada tempat yang tepat untuk
break
dancontinue
untuk digunakan. Faktanya, alasan eksekusi dan penanganan perkecualian diperkenalkan ke bahasa pemrograman modern adalah Anda tidak bisa menyelesaikan setiap masalah hanya dengan menggunakanstructured techniques
.Sebagai tambahan saya tidak ingin memulai diskusi keagamaan di sini tetapi Anda dapat menyusun kembali kode Anda menjadi lebih mudah dibaca seperti ini:
Di sisi lain catatan
Saya pribadi tidak suka penggunaan
( flag == true )
dalam kondisi karena jika variabel sudah menjadi boolean, maka Anda memperkenalkan perbandingan tambahan yang perlu terjadi ketika nilai boolean memiliki jawaban yang Anda inginkan - kecuali tentu saja Anda yakin bahwa kompiler Anda akan optimalkan perbandingan ekstra itu.sumber
boolean
itu atau apa arti terminologi singkat / elegan itu maka mungkin Anda lebih baik menyewa beberapa pengelola yang lebih pintar ;-)Saya setuju dengan bos Anda. Mereka buruk karena mereka menghasilkan metode dengan kompleksitas siklomatik yang tinggi. Metode seperti itu sulit dibaca dan sulit untuk diuji. Untungnya ada solusi mudah. Ekstrak loop body menjadi metode yang terpisah, di mana "melanjutkan" menjadi "kembali". "Kembali" lebih baik karena setelah "kembali" selesai - tidak ada kekhawatiran tentang keadaan setempat.
Untuk "break" ekstrak loop itu sendiri ke metode yang terpisah, ganti "break" dengan "return".
Jika metode yang diekstraksi membutuhkan sejumlah besar argumen, itu indikasi untuk mengekstraksi kelas - baik mengumpulkannya ke objek konteks.
sumber
Saya pikir itu hanya masalah ketika bersarang jauh di dalam banyak loop. Sulit untuk mengetahui loop mana yang Anda hentikan. Mungkin sulit untuk melanjutkan, tetapi saya pikir rasa sakit yang sebenarnya berasal dari istirahat - logika bisa sulit untuk diikuti.
sumber
break 2
; untuk yang lain, saya kira flag bool sementara digunakanSelama mereka tidak digunakan sebagai goto tersamar seperti pada contoh berikut:
Saya baik-baik saja dengan mereka. (Contoh terlihat dalam kode produksi, meh)
sumber
Saya tidak suka gaya ini. Inilah yang saya inginkan:
Saya benar-benar tidak suka menggunakan
return
untuk membatalkan fungsi. Rasanya seperti penyalahgunaanreturn
.Menggunakan
break
juga tidak selalu jelas untuk dibaca.Mungkin lebih baik:
lebih sedikit bersarang dan kondisi kompleks dire-refored menjadi variabel (dalam program nyata Anda harus memiliki nama yang lebih baik, jelas ...)
(Semua kode di atas adalah kode semu)
sumber
break
dancontinue
. Mengakhiri loop secara tidak normal hanya terasa aneh dan saya tidak menyukainya.continue
berarti lewati fungsionalitas, lanjutkan ke loop berikutnya; tidak "lanjutkan dengan eksekusi"Tidak. Ini cara untuk memecahkan masalah, dan ada cara lain untuk menyelesaikannya.
Banyak bahasa arus utama (Java, .NET (C # + VB), PHP, tulis sendiri) menggunakan "break" dan "continue" untuk melewati loop. Keduanya "kalimat terstruktur".
Tanpa mereka:
Dengan mereka:
Perhatikan bahwa kode "break" dan "continue" lebih pendek, dan biasanya mengubah "While" kalimat menjadi "for" atau "foreach".
Kedua kasus adalah masalah gaya pengkodean. Saya lebih suka tidak menggunakannya , karena gaya verbose memungkinkan saya untuk memiliki lebih banyak kontrol kode.
Saya sebenarnya, bekerja di beberapa proyek, di mana wajib menggunakan kalimat-kalimat itu.
Beberapa pengembang mungkin berpikir mereka tidak perlu, tetapi hipotetis, jika kita harus menghapusnya, kita harus menghapus "while" dan "do while" ("ulangi sampai", kalian pascal guys) juga ;-)
Kesimpulan, bahkan jika saya lebih suka untuk tidak menggunakannya, saya pikir ini pilihan, bukan praktik pemrograman yang buruk.
sumber
Saya tidak menentang
continue
danbreak
pada prinsipnya, tetapi saya pikir itu adalah konstruksi tingkat sangat rendah yang seringkali dapat diganti dengan sesuatu yang lebih baik.Saya menggunakan C # sebagai contoh di sini, pertimbangkan kasus keinginan untuk beralih pada koleksi, tetapi kami hanya ingin elemen yang memenuhi beberapa predikat, dan kami tidak ingin melakukan lebih dari maksimal 100 iterasi.
Ini terlihat sangat bersih. Tidak terlalu sulit untuk dimengerti. Saya pikir itu akan berdiri untuk mendapatkan banyak dari menjadi lebih deklaratif. Bandingkan dengan yang berikut ini:
Mungkin di mana dan menerima panggilan bahkan tidak boleh dalam metode ini. Mungkin pemfilteran ini harus dilakukan SEBELUM koleksi dikirimkan ke metode ini. Bagaimanapun, dengan beralih dari hal-hal tingkat rendah dan lebih fokus pada logika bisnis yang sebenarnya, menjadi lebih jelas apa yang benar-benar kami minati. Menjadi lebih mudah untuk memisahkan kode kami menjadi modul kohesif yang lebih berpegang pada praktik desain yang baik dan karenanya di.
Barang-barang tingkat rendah masih akan ada di beberapa bagian kode, tetapi kami ingin menyembunyikan ini sebanyak mungkin, karena dibutuhkan energi mental yang bisa kami gunakan untuk alasan tentang masalah bisnis.
sumber
Kode Lengkap memiliki bagian yang bagus tentang penggunaan
goto
dan beberapa pengembalian dari rutin atau loop.Secara umum itu bukan praktik yang buruk.
break
ataucontinue
katakan apa yang terjadi selanjutnya. Dan saya setuju dengan ini.Steve McConnell (penulis Code Complete) menggunakan contoh yang hampir sama dengan Anda untuk menunjukkan keuntungan menggunakan berbagai
goto
pernyataan.Namun terlalu sering digunakan
break
ataucontinue
dapat menyebabkan perangkat lunak yang kompleks dan tidak terawat.sumber