Mengapa semua orang memberi tahu saya menulis kode seperti ini adalah praktik yang buruk?
if (foo)
Bar();
//or
for(int i = 0 i < count; i++)
Bar(i);
Argumen terbesar saya untuk menghilangkan kurung kurawal adalah kadang-kadang bisa dua kali lebih banyak garis dengan mereka. Sebagai contoh, berikut adalah beberapa kode untuk melukis efek cahaya untuk label dalam C #.
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
{
for (int x = 0; x <= GlowAmount; x++)
{
for (int y = 0; y <= GlowAmount; y++)
{
g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
}
}
}
//versus
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
for (int x = 0; x <= GlowAmount; x++)
for (int y = 0; y <= GlowAmount; y++)
g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
Anda juga bisa mendapatkan manfaat tambahan dari merantai usings
bersama tanpa harus melakukan indentasi jutaan kali.
using (Graphics g = Graphics.FromImage(bmp))
{
using (Brush brush = new SolidBrush(backgroundColor))
{
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
//do lots of work
}
}
}
//versus
using (Graphics g = Graphics.FromImage(bmp))
using (Brush brush = new SolidBrush(backgroundColor))
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
//do lots of work
}
Argumen yang paling umum untuk kurung kurawal berkisar pada pemrograman maintance, dan masalah yang akan terjadi dengan memasukkan kode antara pernyataan asli jika pernyataan dan hasil yang dimaksudkan:
if (foo)
Bar();
Biz();
Pertanyaan:
- Apakah salah jika ingin menggunakan sintaks yang lebih ringkas yang ditawarkan bahasa? Orang-orang yang mendesain bahasa ini cerdas, saya tidak bisa membayangkan mereka akan menempatkan fitur yang selalu buruk untuk digunakan.
- Haruskah kita atau tidakkah kita menulis kode sehingga penyebut umum terendah dapat memahami dan tidak memiliki masalah untuk mengatasinya?
- Apakah ada argumen lain yang saya lewatkan?
Jawaban:
Sebenarnya, satu-satunya waktu yang benar-benar menggigit saya adalah ketika saya sedang debug, dan berkomentar di bar ():
Selain itu, saya cenderung menggunakan:
Yang menangani kasus di atas.
EDIT Terima kasih telah menjelaskan pertanyaan, saya setuju, kita tidak boleh menulis kode ke penyebut umum terendah.
sumber
Kecepatan membaca ...
Selain dari apa yang telah disebutkan. Pada titik ini, saya sudah dikondisikan untuk menguraikan pernyataan dengan kawat gigi dan ruang putih. Jadi saya membaca:
Sedikit lebih cepat daripada yang saya baca:
Saya membacanya sedikit lebih lambat jika terlihat seperti ini:
Saya membaca ini secara signifikan lebih lambat dari sebelumnya:
karena saya tidak bisa tidak membacanya lagi untuk berjaga-jaga dan bertanya-tanya apakah penulis bermaksud:
Sudah dibahas secara umum, tetapi ketika datang untuk membaca di bawah ini, saya akan melihat ini cukup lama untuk memastikan apa yang penulis maksudkan. Saya bahkan dapat memburu penulis asli untuk mengkonfirmasi.
sumber
Jika kecil, tulis seperti ini:
Jika cukup lama untuk dibagi menjadi dua garis, gunakan kawat gigi.
sumber
Dulu saya juga berpikir lebih baik menggunakan kawat gigi saat dibutuhkan. Tetapi tidak lagi, alasan utama, ketika Anda memiliki banyak kode, itu membuatnya lebih mudah dibaca dan Anda dapat menguraikan kode lebih cepat ketika Anda memiliki gaya menguatkan yang konsisten.
Alasan bagus lainnya untuk selalu menggunakan kawat gigi, selain seseorang menambahkan pernyataan kedua ke if, adalah sesuatu seperti ini bisa terjadi:
Apakah Anda memperhatikan bahwa klausa lain sebenarnya adalah "jika (b)"? Anda mungkin melakukannya, tetapi apakah Anda memercayai siapa pun untuk terbiasa dengan gotcha ini?
Jadi, jika hanya untuk konsistensi dan karena Anda tidak pernah tahu hal-hal tak terduga apa yang mungkin terjadi ketika orang lain (selalu orang lain yang bodoh) mengubah kode, saya selalu memasang kawat gigi, karena itu membuat kode sumber lebih mudah dibaca, lebih cepat diurai oleh otakmu. Hanya untuk pernyataan if yang paling sederhana, seperti jika di mana delegasi dibuat atau seperti switch, di mana Anda tahu klausa tidak akan pernah diperpanjang, saya akan meninggalkan kawat gigi.
sumber
!a || !b
) dibandingkan dengan dengan (!a
) atau tanpa (a && !b
) menambahkan kawat gigi.Ini tidak selalu dianggap praktik buruk. The Mono Project Coding Pedoman menyarankan untuk tidak menggunakan kurung kurawal jika tidak diperlukan. Hal yang sama untuk Standar Pengkodean GNU . Saya pikir ini masalah selera pribadi seperti biasa dengan standar pengkodean.
sumber
Garis itu murah. Kekuatan prosesor itu murah. Waktu pengembang sangat mahal.
Sebagai aturan umum, kecuali saya mengembangkan beberapa aplikasi kritis sumber daya / kecepatan, saya akan selalu berbuat salah di sisi penulisan kode yang
(a) Mudah bagi pengembang lain untuk mengikuti apa yang saya lakukan
(B) Komentar bagian tertentu dari kode yang mungkin membutuhkannya
(c) Mudah di-debug jika terjadi kesalahan
(D) Mudah untuk memodifikasi jika perlu di masa depan (yaitu menambah / menghapus kode)
Kecepatan atau keanggunan akademik dari kode adalah faktor sekunder dari faktor-faktor ini dari perspektif Bisnis. Ini bukan untuk mengatakan saya mulai menulis kode yang kikuk atau jelek, tapi ini adalah urutan prioritas SAYA.
Dengan menghilangkan kurung kurawal dalam banyak hal, bagi saya itu membuat (b), (c) dan (d) lebih sulit (perhatikan bukan tidak mungkin). Saya akan mengatakan bahwa menggunakan kurung kurawal atau tidak tidak berpengaruh pada (a).
sumber
Saya lebih suka kejelasan yang ditawarkan kurung kurawal. Anda tahu persis apa yang dimaksud dan tidak perlu menebak jika seseorang hanya melakukan kesalahan dan meninggalkannya (dan memperkenalkan bug). Satu-satunya waktu saya menghilangkannya adalah ketika saya meletakkan if dan action pada baris yang sama. Saya juga tidak sering melakukannya. Saya sebenarnya lebih suka spasi putih yang diperkenalkan dengan menempatkan kurung kurawal pada jalurnya sendiri, meskipun dari bertahun-tahun pemrograman K&R C, mengakhiri garis dengan kurawal adalah praktik yang harus saya atasi jika IDE tidak menerapkannya untuk saya.
sumber
Saya pikir ini masalah pedoman untuk proyek yang sedang Anda kerjakan dan selera pribadi.
Saya biasanya menghilangkannya ketika tidak diperlukan, kecuali beberapa kasus seperti berikut:
saya lebih memilih
sumber
Salah satu contoh di mana ini dapat menggigit Anda adalah kembali di masa lalu makro C / C ++. Saya tahu ini adalah pertanyaan C #, tetapi sering kali pengkodean standar terbawa tanpa alasan mengapa standar itu dibuat.
Jika Anda tidak terlalu berhati-hati saat membuat makro, Anda dapat menyebabkan masalah dengan pernyataan if yang tidak menggunakan {}.
Sekarang, jangan salah paham, saya tidak mengatakan bahwa Anda harus selalu melakukan {} hanya untuk menghindari masalah ini di C / C ++, tapi saya harus berurusan dengan beberapa bug yang sangat aneh karena ini.
sumber
Dulu saya berpikir dengan cara yang sama.
Sampai suatu hari (mengapa selalu ada "satu hari" yang mengubah hidup Anda selamanya?) Kami menghabiskan 24 - 36 jam berturut-turut tanpa tidur men-debug kode produksi hanya untuk mengetahui bahwa seseorang tidak memasang kawat gigi yang dikombinasikan dengan perubahan pencarian / ganti .
Sesuatu seperti ini.
Apa yang terjadi kemudian adalah
Ternyata sistem tersebut menghasilkan 500 mb log setiap hari dan kami diminta untuk menghentikannya. Bendera debug tidak cukup sehingga pencarian dan ganti println dilakukan.
Masih ketika aplikasi pergi ke produksi bendera debug dimatikan dan "saveDayData" yang penting tidak pernah dipanggil.
EDIT
Sekarang satu-satunya tempat di mana saya tidak menggunakan kawat gigi adalah jika saya mencoba membangun.
Setelah menonton seorang pengembang superstar melakukan itu.
sumber
Terus terang saya melihatnya sebagai:
Pemrogram yang baik memprogram pertahanan, Pemrogram jahat tidak.
Karena ada beberapa contoh di atas dan pengalaman saya sendiri yang serupa dengan bug yang terkait dengan lupa kawat gigi maka saya belajar cara yang sulit untuk SELALU PUT BRACES.
Yang lainnya adalah memilih gaya pribadi daripada keselamatan dan itu jelas pemrograman yang buruk.
Joel bahkan menyebutkan ini di Making Wrong Code Look Wrong
Setelah Anda mendapatkan sedikit bug karena kawat gigi yang hilang, Anda mengetahui bahwa kawat gigi yang hilang terlihat salah karena Anda tahu itu adalah tempat yang potensial untuk bug lain terjadi.
sumber
if
pernyataan mengontrol blok, tetapi menghindari perlunya blok dalam kasus di manaif
pernyataan mengontrol tindakan tunggal daripada blok.Saya cukup senang untuk:
Secara pribadi, saya tidak mengerti mengapa
lebih mudah dibaca.
Ya, baris gratis, tetapi mengapa saya harus menggulir halaman dan halaman kode ketika ukurannya bisa setengah?
Jika ada perbedaan dalam keterbacaan atau pemeliharaan maka, tentu saja, pasang kawat gigi di ... tetapi dalam kasus ini saya tidak melihat alasan untuk itu.
Juga, saya akan selalu meletakkan kawat gigi untuk bersarang jika di mana saya bersarang di tempat lain
vs.
sangat membingungkan, jadi saya selalu menuliskannya sebagai:
Kapan pun memungkinkan, saya menggunakan operator ternary, tetapi saya tidak pernah membuat sarangnya .
sumber
Saya setuju bahwa "jika Anda cukup pintar untuk membuat seseorang membayar Anda untuk menulis kode, Anda harus cukup pintar untuk tidak hanya bergantung pada lekukan untuk melihat aliran kode."
Namun ... kesalahan bisa dibuat, dan yang ini sulit untuk di-debug ... terutama jika Anda datang melihat kode orang lain.
sumber
Filosofi saya adalah jika membuat kode lebih mudah dibaca, mengapa tidak melakukannya?
Jelas Anda harus menggambar garis di suatu tempat, seperti menemukan media yang bahagia antara nama variabel yang singkat dan deskriptif. Tetapi kurung benar-benar menghindari kesalahan dan meningkatkan keterbacaan kode.
Anda dapat berargumen bahwa orang yang cukup pintar untuk menjadi pembuat kode akan cukup pintar untuk menghindari bug yang memunculkan pernyataan tanpa bracket. Tetapi bisakah Anda dengan jujur mengatakan Anda tidak pernah tersandung oleh sesuatu yang sederhana seperti kesalahan ejaan? Minutia seperti ini bisa luar biasa ketika melihat proyek-proyek besar.
sumber
Selalu ada pengecualian, tapi saya akan membantah menghilangkan kawat gigi hanya jika ada di salah satu bentuk:
Kalau tidak, saya tidak punya masalah dengan itu.
sumber
Saya kadang-kadang menggunakan kode paling bawah (banyak menggunakan pernyataan), tetapi selain itu saya selalu memasukkan kurung. Saya hanya menemukan itu membuat kode lebih jelas. Jelas sekali dari lebih dari sekadar indentasi bahwa pernyataan adalah bagian dari blok (dan karenanya mungkin bagian dari if, dll).
Saya telah melihat
bug menggigit saya (atau lebih tepatnya "saya dan kolega" - saya tidak benar-benar memperkenalkan bug) sekali . Ini terlepas dari kenyataan bahwa standar pengkodean kami pada waktu itu merekomendasikan penggunaan kawat gigi di mana-mana. Secara mengejutkan saya butuh waktu lama untuk menemukan - karena Anda melihat apa yang ingin Anda lihat. (Ini sekitar 10 tahun yang lalu. Mungkin saya akan menemukannya lebih cepat sekarang.)
Tentu saja jika Anda menggunakan "penjepit di ujung garis" itu mengurangi garis tambahan yang terjadi, tetapi saya pribadi tidak menyukai gaya itu. (Saya menggunakannya di tempat kerja, dan menganggapnya kurang menyenangkan daripada yang saya harapkan, tetapi masih sedikit tidak menyenangkan.)
sumber
Saya terkesan dan rendah hati bahwa rekan-rekan saya di bidang pemrograman komputer (Anda banyak) tidak gentar dengan prospek bug potensial ketika Anda melewatkan kawat gigi pada blok baris tunggal.
Saya kira itu berarti saya tidak pintar. Saya telah membuat kesalahan sekitar ini beberapa kali. Saya telah membantah kesalahan orang lain dalam hal ini. Saya telah menonton perangkat lunak kapal dengan bug karena ini (RDP ke mesin yang menjalankan VS2002 dan font jendela arloji Anda akan miring).
Jika saya melihat semua kesalahan yang saya buat yang bisa dihindari dengan perubahan gaya pengkodean, daftarnya sangat panjang. Jika saya tidak mengubah pendekatan saya dalam setiap kasus ini, saya mungkin tidak akan pernah berhasil sebagai programmer. Sekali lagi, saya kira saya tidak pintar. Untuk mengimbangi, saya telah menjadi pengguna yang kuat kawat gigi pada blok baris tunggal untuk waktu yang lama.
Yang mengatakan, beberapa hal telah berubah di dunia yang membuat "kamu harus menggunakan kawat gigi pada blok tunggal" aturan hari ini kurang relevan daripada ketika Musa membawanya ke kita:
Beberapa bahasa populer membuat masalah hilang dengan membuat komputer membaca lekukan, seperti yang dilakukan oleh programmer (misalnya Python).
Editor saya secara otomatis memformat untuk saya, sehingga kemungkinan saya menyesatkan oleh indentasi jauh berkurang.
TDD berarti bahwa jika saya memperkenalkan bug karena saya bingung oleh blok satu baris, saya jauh lebih mungkin untuk menemukan bug dengan cepat.
Refactoring dan pengekspresian bahasa berarti bahwa blok saya jauh lebih pendek, dan blok satu garis terjadi lebih sering daripada biasanya. Hipotetis, dengan aplikasi ExtractMethod yang kejam, saya mungkin hanya punya satu baris blok di seluruh program saya. (Aku ingin tahu seperti apa itu nantinya?)
Faktanya, ada manfaat berbeda yang bisa didapat dari refactoring tanpa ampun & menghilangkan kawat gigi pada blok satu baris: ketika Anda melihat kawat gigi, sedikit alarm dapat berbunyi di kepala Anda yang mengatakan "kompleksitas di sini! Waspadalah!". Bayangkan jika ini adalah norma:
Saya membuka diri pada gagasan untuk mengubah konvensi pengkodean saya menjadi sesuatu seperti "blok baris tunggal mungkin tidak pernah memiliki kawat gigi" atau "jika Anda dapat meletakkan blok pada baris yang sama dengan kondisi, dan semuanya cocok dalam 80 karakter, hilangkan kawat gigi ". Kita lihat saja nanti.
sumber
Dari tiga konvensi:
dan:
dan (yang mewakili gaya lekukan apa pun menggunakan brace pembuka dan penutup):
Saya lebih suka yang terakhir sebagai:
sumber
Argumen utama Anda yang menentang penggunaan kawat gigi adalah bahwa mereka menggunakan garis tambahan dan mereka membutuhkan indentasi tambahan.
Baris (hampir) gratis, meminimalkan jumlah baris dalam kode Anda seharusnya tidak menjadi tujuan.
Dan indentasi tidak tergantung pada penggunaan brace. Dalam contoh 'menggunakan' cascading Anda, saya masih berpikir Anda harus membuat indentasi bahkan ketika Anda menghilangkan kawat gigi.
sumber
Saya sangat percaya dalam menulis kode yang rapi dan ringkas, tetapi saya akan selalu menggunakan kurung kurawal. Saya menemukan bahwa mereka adalah cara yang mudah untuk dengan cepat melihat ruang lingkup di mana baris kode tertentu ada. Tidak ada ambiguitas, itu hanya secara eksplisit ditetapkan di depan Anda.
Beberapa orang mungkin mengatakan itu adalah kasus preferensi, tetapi saya menemukan aliran logis dari suatu program jauh lebih mudah untuk diikuti jika itu konsisten secara internal, dan saya tidak percaya bahwa itu konsisten untuk menulis satu pernyataan IF seperti ini;
Dan yang lain seperti ini;
Saya lebih suka hanya memilih satu gaya umum dan tetap menggunakannya :)
sumber
Salah satu masalah utama adalah ketika Anda memiliki wilayah one-liners dan non-one liner, bersama dengan pemisahan dari statment kontrol (
for
,if
, apa yang harus Anda) dan akhir pernyataan tersebut.Sebagai contoh:
sumber
Saya dulunya adalah pendukung besar "kurung kurawal adalah suatu KEHARUSAN!", Tetapi sejak mengadopsi pengujian unit, saya menemukan bahwa pengujian unit saya melindungi pernyataan tanpa gelang dari skenario seperti:
Dengan tes unit yang baik, saya dapat dengan yakin menghilangkan kurung kurawal untuk pernyataan sederhana untuk meningkatkan keterbacaan (ya, itu bisa subjektif).
Atau, untuk sesuatu seperti di atas, saya mungkin akan menunjukkan bahwa:
Dengan begitu, pengembang yang perlu menambahkan bilah () ke kondisi, akan lebih cenderung mengenali kurangnya kurung kurawal, dan menambahkannya.
sumber
Gunakan penilaian pribadi.
baik-baik saja dengan sendirinya. Kecuali jika Anda benar-benar khawatir tentang orang bodoh memasukkan sesuatu seperti ini nanti:
Jika Anda tidak khawatir dengan orang bodoh, Anda baik-baik saja (saya tidak - jika mereka tidak bisa mendapatkan sintaksis kode dasar dengan benar, ini adalah masalah mereka yang paling kecil)>
Sebagai gantinya, itu jauh lebih mudah dibaca.
Sisa waktu:
Yang telah menjadi favorit saya selama saya bisa ingat. Selain itu:
Bekerja untukku.
Ruang vertikal dengan sendirinya tidak terlalu relevan, keterbacaan adalah. Brace pembuka pada baris dengan sendirinya hanya menghentikan percakapan untuk elemen sintaksis, sampai mata Anda bergerak ke bawah ke baris berikutnya. Bukan yang aku suka.
sumber
if (parameter == null) return null;
.Oke, ini pertanyaan lama yang sudah dijawab sampai mati. Saya punya sesuatu untuk ditambahkan.
Pertama saya hanya harus mengatakan GUNAKAN BRASES. Mereka hanya dapat membantu keterbacaan, dan keterbacaan (untuk diri sendiri dan orang lain!) Harus sangat tinggi pada daftar prioritas Anda kecuali Anda menulis perakitan. Kode yang tidak dapat dibaca selalu, selalu mengarah ke bug. Jika Anda menemukan bahwa kawat gigi membuat kode Anda menghabiskan terlalu banyak ruang, metode Anda mungkin terlalu lama. Sebagian besar atau semua metode apa pun harus masuk dalam satu ketinggian layar jika Anda melakukannya dengan benar, dan Find (F3) adalah teman Anda.
Sekarang untuk tambahan saya: Ada masalah dengan ini:
Coba atur breakpoint yang hanya akan mengenai jika bar () akan dijalankan. Anda dapat melakukan ini di C # dengan meletakkan kursor pada bagian kedua dari kode, tetapi itu tidak jelas dan sedikit menyusahkan. Di C ++ Anda tidak bisa melakukannya sama sekali. Salah satu pengembang paling senior kami yang bekerja pada kode C ++ bersikeras untuk melanggar pernyataan 'jika' menjadi dua baris karena alasan ini. Dan saya setuju dengannya.
Jadi lakukan ini:
sumber
untuk menjaga agar kode dengan kawat gigi tidak memakan banyak ruang, saya menggunakan teknik yang direkomendasikan dalam buku, Lengkap :
sumber
if
yang diikuti oleh garis indentasi tunggal dapat secara visual diakui sebagai mengendalikan pernyataan tunggal tanpa perlu kawat gigi apa pun. Gaya open-brace-by-sendirinya dengan demikian menghemat ruang putih dalam situasi di manaif
pernyataan mengontrol sesuatu yang secara semantik merupakan tindakan tunggal (berbeda dari urutan langkah yang kebetulan hanya berisi satu langkah tunggal). Sebagai contoh,if (someCondition)
/ `lempar SomeException (...)` baru.Katakanlah Anda memiliki beberapa kode:
dan kemudian orang lain datang dan menambahkan:
Menurut cara ini ditulis, bar (); sekarang dijalankan tanpa syarat. Dengan memasukkan kurung kurawal, Anda mencegah kesalahan tak disengaja semacam ini. Kode harus ditulis sedemikian rupa untuk membuat kesalahan seperti itu sulit atau tidak mungkin dilakukan. Jika saya melakukan review kode dan melihat kawat gigi yang hilang, terutama tersebar di beberapa baris, saya akan membuat cacat. Dalam kasus di mana itu dibenarkan, tetap di satu baris sehingga kemungkinan membuat kesalahan seperti itu dijaga agar tetap minimum.
sumber
Mengurangi garis sebenarnya bukan argumen yang bagus untuk menjatuhkan kawat gigi. Jika metode Anda terlalu besar, itu mungkin harus di refactored menjadi potongan-potongan kecil atau direstrukturisasi. Melakukan itu tidak diragukan lagi akan meningkatkan keterbacaan lebih dari sekadar mengambil kawat gigi.
sumber
Saya selalu menghilangkannya jika perlu, seperti pada contoh pertama Anda. Bersihkan, kode ringkas yang dapat saya lihat dan pahami dengan melirik lebih mudah untuk mempertahankan, men-debug dan memahami daripada kode yang harus saya gulir dan baca baris demi baris. Saya pikir sebagian besar programmer akan setuju dengan ini.
Sangat mudah untuk keluar dari tangan jika Anda mulai melakukan beberapa sarang, jika / lain klausa dan sebagainya, tapi saya pikir sebagian besar programmer harus bisa mengatakan di mana harus menggambar garis.
Aku melihatnya jenis seperti argumen untuk
if ( foo == 0 )
vsif ( 0 == foo )
. Yang terakhir dapat mencegah bug untuk programmer baru (dan mungkin bahkan kadang-kadang untuk veteran), sedangkan yang pertama lebih mudah untuk dengan cepat membaca dan memahami ketika Anda mempertahankan kode.sumber
Sering kali sudah tertanam sebagai standar pengkodean, baik untuk perusahaan atau proyek FOSS.
Pada akhirnya, orang lain perlu mengosongkan kode Anda dan itu adalah waktu yang menguras waktu bagi setiap pengembang untuk mengetahui gaya khusus dari bagian kode yang mereka kerjakan.
Juga, bayangkan bahwa seseorang pergi antara Python dan bahasa Cish lebih dari sekali sehari ... Dalam Python indentasi adalah bagian dari blok symantics bahasa dan akan sangat mudah untuk membuat kesalahan seperti yang Anda kutip.
sumber
Kesalahan di sisi yang lebih aman - hanya satu bug lagi yang berpotensi tidak perlu Anda perbaiki.
Saya pribadi merasa lebih aman jika semua balok saya terbungkus keriting. Bahkan untuk one-liners, ini adalah notasi sederhana yang mudah mencegah kesalahan. Itu membuat kode lebih mudah dibaca dalam arti bahwa Anda melihat dengan jelas apa yang ada di blok agar tidak membingungkan tubuh blok dengan pernyataan berikut di luar blok.
Jika saya memiliki satu-liner, saya biasanya memformatnya sebagai berikut:
Jika saluran terlalu rumit maka gunakan yang berikut ini:
sumber