Pemeliharaan bijaksana, apakah `selain sementara` tanpa kawat gigi intervensi dianggap aman?

26

Apakah else whiletanpa kawat gigi intervensi dianggap pemeliharaan yang "aman"?

Menulis if-elsekode tanpa kawat gigi seperti di bawah ini ...

if (blah)
    foo();
else
    bar();

... membawa risiko karena kurangnya kawat gigi membuatnya sangat mudah untuk mengubah makna kode secara tidak sengaja.

Namun, apakah di bawah ini juga berisiko?

if (blah)
{
    ...
}
else while (!bloop())
{
    bar();
}

Atau apakah else whiletanpa kawat gigi intervensi dianggap "aman"?

Mehrdad
sumber
20
bagiku else whileterlihat menjijikkan. Saya akan menggunakan else { while (condition) { ... } }.
Joachim Sauer
7
Saya pikir itu terlalu subjektif untuk jawaban yang tepat ... Saya sendiri tidak akan melakukannya karena saya tidak akan mengharapkan loop di sana, dan berpikir saya tidak berharap membuat keterbacaan sulit.
johannes
7
Saya akan mengekstrak metode untuk sementara-barang
nyamuk
12
Jujur, itu membuatku merinding. ifhanya dievaluasi sekali, tetapi whilemenunjukkan satu loop, jadi menghubungkan keduanya memberi saya perasaan tidak berdasar bahwa itu ifadalah bagian dari loop ... entah bagaimana ...
user281377
4
Dan bagaimana jika dalam elseklausa Anda ingin melakukan while dan melakukan sesuatu yang lebih? Silakan gunakan kawat gigi saja.
Carlos Campderrós

Jawaban:

57

Itu mengingatkan saya pada kode ini:

if ( ... ) try {
..
} catch (Exception e) {
..
} else {
...
}

Setiap kali Anda menggabungkan dua jenis blok, melupakan kawat gigi dan tidak meningkatkan indentasi, Anda membuat kode yang sangat sulit untuk dipahami dan dipelihara.

Sulthan
sumber
18
Contoh yang baik. Sungguh cara yang mengerikan untuk menulisnya.
Leo
4
Wow, jawaban ini sangat meyakinkan!
Mehrdad
Anda dapat dengan mudah mengatur IDE modern untuk secara otomatis memformat kode pada penyimpanan - termasuk memasukkan kawat gigi dan memperbaiki indentasi. Jadi ini hanya setengah argumen. Indentasi yang benar ini tidak menimbulkan masalah untuk keterbacaan, apakah ada kawat gigi atau tidak.
Hans-Peter Störr
55

Mungkin itu karena saya mempelajari perdagangan saya (jalan kembali ketika) menggunakan metode Diagram Struktur Entitas Jackson , tetapi saya berlangganan dengan pandangan bahwa satu-satunya istilah yang tidak di-brace yang benar setelah suatu ifatau yang elseberikutnya adalah if(yaitu mengizinkan else iftangga)

Hal lain (tidak ada permainan kata-kata) meninggalkan potensi untuk kesalahpahaman dan / atau masalah pemeliharaan. Itulah aspek utama dari ide OP menjadi "tidak aman".

Saya juga akan sangat cerdik tentang memasukkan while()pada baris yang sama dengan else- apakah menguatkan atau tidak. Itu tidak tepat bagi saya ... tidak ada topeng lekukan tambahan bahwa itu adalah elseklausa. Dan kurangnya kejelasan membuat kesalahpahaman (lihat di atas).

Jadi dalam contoh ini saya akan sangat menyarankan / merekomendasikan (dan bersikeras, di tim saya) tentang:

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Tentu saja, saya juga berharap untuk melihat komentar yang cocok juga.

- Edit -

Baru-baru ini Apple menderita kerentanan SSL, yang disebabkan oleh perbaikan pemeliharaan yang buruk - yang menambahkan baris kedua ke saluran tunggal yang tidak di-resleting. Jadi mari kita taruh ide bahwa satu baris yang tidak diikat tidak apa-apa?

Andrew
sumber
2
Saya setuju jika menjadi satu-satunya istilah yang benar untuk mengikuti yang lain. Jika ada, else whilesaya mungkin tidak akan memperhatikan ada loop dalam skimming cepat kode, terutama jika kondisi yang saya cari puas dengan if.
Drake Clarris
3
Itu lucu. Semua orang mengatakan bahwa lebih mudah dibaca jika semuanya ada dalam kawat gigi. Saya menemukan yang sebaliknya benar. Jika hanya satu pernyataan, tidak menggunakan kawat gigi membuatnya lebih mudah dibaca. Kurang berantakan. Mungkin hanya karena saya selalu melakukannya dengan cara itu.
Jeff Davis
2
@ Jeff Jvis itu tangkapan yang bagus. "Lebih mudah dibaca" adalah undangan khas untuk perang suci yang tidak berguna. Saya untuk satu lebih suka kawat gigi, tetapi bukan karena sampah "simplertoread" yang tidak relevan (bagi saya misalnya justru sebaliknya) tetapi karena lebih sulit untuk istirahat dalam pemeliharaan kode lebih lanjut. Omong-omong, OP mengejanya dengan lebih baik dalam pertanyaan mereka: apakah else whiletanpa kawat gigi yang mengintervensi dianggap "aman" ?
nyamuk
@JeffDavis - Saya tahu utas ini berumur dua tahun, tetapi Apple baru-baru ini menemukan mengapa tidak menggunakan kawat gigi bukan ide yang bagus andrewbanks.com/...
Andrew
@Andrew Omong-omong, bahasa Swift Apple sekarang secara eksplisit melarang kontrol aliran satu baris. Bug itu bisa menjadi salah satu alasan untuk melakukannya.
Sulthan
6

Saya selalu diajarkan untuk menjaga segala sesuatunya dalam kawat gigi, menjorok dan berkomentar. Saya percaya akan lebih mudah untuk membaca dan menemukan kesalahan. Secara pribadi saya merasa modularitas adalah kunci sehingga saya akan selalu menulis kode seperti ini:

    if(blah)
    {
     ....
    }
    else
    {
       while(!bloop()
       {
        bar;
       }
    }
CodeCompileHack
sumber
6

Saya akan mengekstrak metode dan membuatnya

if ( blah )
{
    ...
}
else
{
   newMethod();
}

Lihat pendekatan "ekstrak metode" yang dijelaskan di situs Katalog Refactoring :

Anda memiliki fragmen kode yang dapat dikelompokkan bersama.

Ubah fragmen menjadi metode yang namanya menjelaskan tujuan metode.

void printOwing() {
    printBanner();

    //print details
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + getOutstanding());
}

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + outstanding);
}
pengguna470365
sumber
Tergantung ... jika misalnya, loop sementara menggunakan data tingkat fungsi, Anda sekarang harus lebih banyak data ke modul (atau kelas, jika menggunakan tingkat C ++). Dan jika hanya potongan kecil kode, Anda menggunakan metode sepele. Tapi kadang-kadang, tergantung keadaan, saya setuju.
Andrew
1
+1 Kompiler Smart C ++ dapat menampilkan fungsi. Dalam lingkungan Bersih. Fungsi kecil lebih baik karena JIT.
Pekerjaan
4

Saya akan menganggapnya sebagai kebiasaan buruk pengkodean. Terkadang ini berfungsi dengan baik dan Anda tidak akan memiliki masalah dalam menyusun dan menjalankan kode. Di lain waktu itu dapat menyebabkan bug serius dan Anda akan menghabiskan waktu berjam-jam untuk memperbaiki bug itu.

Itu selalu disarankan untuk memodulasi kode Anda. Jika Anda harus meletakkan loop sementara di bagian lain letakkan di blok sehingga orang lain, ketika bekerja pada kode Anda dapat dengan mudah memahami logika.

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Ini adalah praktik yang baik untuk meletakkan kode di blok. Itu membuatnya lebih sederhana dan lebih mudah untuk memahami dan men-debug juga.

Sandeep Gupta
sumber
4

Mungkin baik-baik saja jika tetap sederhana seperti itu meskipun secara pribadi saya tidak menyukainya dan preferensi saya adalah menggunakan kawat gigi bahkan untuk blok kode if / else yang paling sederhana. Ini lebih rapi untuk saya.

Namun, di mana ini menjadi berantakan adalah ketika Anda telah bersarang jika / lain loop beberapa dengan kawat gigi beberapa tanpa A While loop di tengah semua spageti itu! Saya telah bekerja dengan kode yang buruk dan itu mimpi buruk untuk debug dan mengerti. Ini mengikuti dari titik pertama itu baik-baik saja ketika itu tetap sederhana dan Anda senang dengan itu, tetapi kemudian programmer lain datang dan menambahkan sesuatu ke dalamnya, mungkin jika ada di dalam while loop. Jika itu ditulis bersih di tempat pertama maka ada sedikit kemungkinan hal ini terjadi.

Intinya adalah membuat hal-hal menjadi jelas sehingga programmer lain dapat melihat secara sekilas apa yang benar dan salah. Tulis kode sehingga polanya terlihat benar dan tidak bergetar.

Sisi lain dari hal ini adalah mungkin saya bisa melihat beberapa orang mengklaim bahwa dalam kasus tertentu ini bisa dibaca dengan baik. Jika saya punya sumber daya, saya perlu melakukan pemrosesan ini sementara saya menunggu sesuatu melakukan ini. Meski begitu bagi saya masih ada perbedaan dalam bersarang loop sementara di dalam blok lain.

Daniel Hollinrake
sumber
3

Yah, meskipun semua orang berdebat tentang menggunakan kawat gigi dan tampaknya mencintai mereka, saya sebenarnya lebih suka sebaliknya. Saya hanya menggunakan kawat gigi ketika saya harus melakukannya karena saya merasa lebih mudah dibaca dan ringkas tanpa.

if (...)
   foo();
else while(...)
   bar();

... " else while(...)" Saya benar-benar menemukan ini sangat bisa dibaca! Bahkan berbunyi seperti bahasa Inggris! Tapi saya kira semua orang akan menganggapnya aneh karena jarang dikatakan.

Pada akhirnya, kita semua cenderung menjadikannya anti-idiot dengan kawat gigi ... karena, yah, Anda tahu.

dagnelies
sumber
3
itu akan sangat mudah dibaca setelah beberapa pengelola yang tidak bersalah berubah else while(...) bar();menjadi sesuatu seperti else while(...) foobar(); bar();:)
Agas
3
well, saya akan mengatakan bahwa itu adalah seorang pemelihara yang sangat bodoh dan berbahaya . Saya tahu prinsip mematikannya untuk menghindari kesalahan bodoh ... tapi sejauh ini cukup menyedihkan. Tapi saya tahu saya akan mendapatkan komentar dan downvotes seperti itu. Tidak masalah.
dagnelies
2
"Selalu kode seolah-olah orang yang akan mempertahankan kode Anda adalah psikopat kejam yang tahu di mana Anda tinggal." ( Alan Braggins )
nyamuk
1
Nah, semuanya bermuara pada apa yang Anda anggap tingkat paling bodoh dari seseorang yang bekerja pada kode Anda. Saya berpendapat bahwa jika "maintainer" Anda mendapat confuser oleh keempat baris kode ini ... maka Anda memiliki masalah besar. Dan jika itu psikopat keras, Anda punya dua. ;)
dagnelies
1
jika - yah tautan yang saya rujuk di atas, telah memperluas versi kutipan ini: Programmer 1: 'Ada kutipan yang bagus di sini - "Selalu kode seolah-olah orang yang akan mempertahankan kode Anda adalah psikopat kejam yang tahu di mana Anda tinggal"' . Programmer 2: (Melihat ke arah pengelola) 'Apa maksudmu "seolah-olah"?'
nyamuk
2

Saya selalu memasang kawat gigi, hanya karena Anda dapat menambahkan baris lain saat terburu-buru, indentasi, lupakan kawat gigi dan garuk-garuk kepala Anda apa yang terjadi. Saya menjaga braket pembuka pada baris yang sama, tetapi tidak masalah. Saya berdua lebih baik memilikinya.

if(blah) {
    foo();
}
else {
    bar();
}
Tsvetomir Dimitrov
sumber
Penentuan posisi kawat gigi mungkin memicu lebih banyak argumen daripada apa pun di luar (atau mungkin termasuk) agama!
Andrew
Sepakat. Akan mengedit jawaban saya untuk menekankan pada keberadaan mereka, bukan posisi.
Tsvetomir Dimitrov
2

Apa yang salah dengan kawat gigi sehingga banyak orang berusaha untuk tidak menulisnya?

Masalah apa sebenarnya yang else whiledipecahkan?

Kawat gigi murah dan bagus, dan mereka membuat niat kode menjadi jelas dan jelas sebagai lawan pintar dan cerdas.

Mengutip Filsafat Unix:

Aturan Kejelasan: Kejelasan lebih baik dari pada kepintaran.

Karena pemeliharaan sangat penting dan sangat mahal, tulislah program seolah-olah komunikasi terpenting yang mereka lakukan bukanlah ke komputer yang mengeksekusinya tetapi kepada manusia yang akan membaca dan memelihara kode sumber di masa mendatang (termasuk diri Anda).

Tulains Córdova
sumber
1

Tidak ada yang salah dengan itu

if (blah)
    foo();
else
    bar();

sama seperti tidak ada yang salah dengan itu

if (blah) foo(); else bar();

dalam keadaan yang tepat (keadaan Anda mungkin berbeda-beda, tetapi gaya tertentu itu paling baik digunakan ketika Anda memiliki banyak kode berulang - maka tampilan setiap baris lebih penting daripada lekukan gaya)

Tetapi jika Anda memilih satu cara, pertahankan - konsistensi adalah raja. Jadi contoh kedua Anda sangat buruk, karena ekspresi if memiliki tanda kurung untuk pernyataannya, pernyataan sementara harus di dalam tanda kurung untuk klausa lain, bukan di luarnya.


selain itu, saya telah melihat kode ini sebelumnya:

if (x) foo()
{
  bar();
}

dan itu ditulis oleh standar pengkodean nazi sendiri (yang bersikeras tanda kurung untuk semuanya).

gbjbaanb
sumber
1

IDE modern dapat dengan mudah dikonfigurasikan untuk memformat ulang (termasuk menghapus atau menambahkan kawat gigi yang tidak perlu) dan / atau mengaktifkan kembali kode untuk menyimpan file. Jadi contoh Anda akan secara otomatis terlihat seperti misalnya

if (blah) {
  blub();
} else
  while (!bloop()) {
    bar();
  }

Lekukan selalu membuat sarang mudah terlihat, bahkan tanpa kawat gigi yang tidak perlu. Jadi, jika Anda berhasil menerapkan pengaturan IDE seperti itu, saya tidak melihat risiko.

Secara pribadi, saya menemukan kode yang menghilangkan kawat gigi dan linebreak jauh lebih mudah dibaca karena menghindari kekacauan:

if (blah) blub();
else while (!bloop()) bar();

Tapi tentu saja, banyak pengembang sangat senang berdebat tentang hal-hal seperti itu selamanya dan sehari.

Hans-Peter Störr
sumber