Hal-hal mana yang langsung membunyikan lonceng alarm ketika melihat kode? [Tutup]

98

Saya menghadiri acara pengerjaan perangkat lunak beberapa minggu yang lalu dan salah satu komentar yang dibuat adalah "Saya yakin kita semua mengenali kode buruk ketika kita melihatnya" dan semua orang mengangguk dengan bijak tanpa diskusi lebih lanjut.

Hal semacam ini selalu membuat saya khawatir karena ada disangkal bahwa semua orang berpikir mereka adalah pengemudi di atas rata-rata. Meskipun saya pikir saya bisa mengenali kode buruk, saya ingin belajar lebih banyak tentang apa yang orang lain anggap sebagai kode bau karena jarang dibahas secara rinci di blog orang dan hanya di segelintir buku. Khususnya saya pikir akan menarik untuk mendengar tentang apa pun yang merupakan bau kode dalam satu bahasa tetapi bukan yang lain.

Saya akan mulai dengan yang mudah:

Kode dalam kontrol sumber yang memiliki proporsi tinggi kode komentar - mengapa ada di sana? apakah itu dimaksudkan untuk dihapus? Apakah itu pekerjaan setengah jadi? mungkin itu seharusnya tidak dikomentari dan hanya dilakukan ketika seseorang sedang menguji sesuatu? Secara pribadi saya menemukan hal semacam ini sangat mengganggu bahkan jika itu hanya garis aneh di sana-sini, tetapi ketika Anda melihat blok besar diselingi dengan sisa kode itu benar-benar tidak dapat diterima. Ini juga biasanya merupakan indikasi bahwa sisa kode kemungkinan memiliki kualitas yang meragukan juga.

FinnNk
sumber
61
Saya terkadang menemukan orang yang berkomentar kode keluar, checkin dan berkata "Saya mungkin membutuhkannya lagi di masa depan - jika saya menghapusnya sekarang saya akan kehilangan itu". Saya harus membalas dengan "Er, ... tapi untuk itulah kontrol sumber".
talonx
6
Terkadang, terutama saat mengoptimalkan, akan berguna untuk meninggalkan kode lama sebagai komentar, sehingga Anda tahu apa yang digantikan oleh kode yang dioptimalkan tidak jelas. Pikirkan untuk meninggalkan swap 3 baris dengan temp di tempat ketika menggantinya dengan swap twiddling bit satu baris. (Meskipun, saya melihat tidak perlu menggunakan swap satu baris - PERNAH, kecuali ukuran program sangat penting.)
Chris Cudmore
4
Saya menjaga / membersihkan kode yang ditulis oleh salah satu teknisi kami, yang mengkodekan beberapa hal berguna tetapi mengakui bahwa ia bukan seorang programmer. Ketika saya mengkonsolidasikan hal-hal saya akan mengomentari kode lamanya dan kemudian kita membahas perubahan dan saya menunjukkan kepadanya bagaimana saya menggantikannya dengan sesuatu yang lebih kecil / lebih efisien / lebih mudah dimengerti. Setelah itu saya menghapus blok-blok itu kemudian saya memeriksanya. Memiliki kode lama di sana memiliki manfaat karena dia melihat bagaimana hal-hal dapat dilakukan lebih sederhana dan saya dapat mengingat mengapa saya mengubah hal-hal ketika kita berbicara.
the Tin Man
8
Saya meninggalkan hal-hal yang "dapat digunakan" untuk 1 komit, maka jika hal-hal tidak rusak atau kebutuhan tidak ditemukan, itu akan dihapus pada komit berikutnya.
Paul Nathan
24
Hmm. printf("%c", 7)biasanya membunyikan bel alarm untuk saya. ;)

Jawaban:

128
/* Fuck this error */

Biasanya ditemukan di dalam try..catchblok omong kosong , itu cenderung menarik perhatian saya. Hampir sama baiknya /* Not sure what this does, but removing it breaks the build */.

Beberapa hal lagi:

  • Beberapa ifpernyataan kompleks bersarang
  • Blok coba-tangkap yang digunakan untuk menentukan aliran logika secara teratur
  • Fungsi dengan nama generik process, data, change, rework,modify
  • Enam atau tujuh gaya penahan yang berbeda dalam 100 baris

Yang baru saya temukan:

/* Stupid database */
$conn = null;
while(!$conn) {
    $conn = mysql_connect("localhost", "root", "[pass removed]");
}
/* Finally! */
echo("Connected successfully.");

Benar, karena harus memaksa koneksi MySQL Anda adalah cara yang tepat untuk melakukan sesuatu. Ternyata database itu mengalami masalah dengan jumlah koneksi sehingga mereka terus waktu. Alih-alih men-debug ini, mereka hanya mencoba lagi dan lagi sampai berhasil.

Josh K
sumber
19
Kalau saja saya bisa mengungguli ini 6 kali! Semua contoh bagus. Saya juga tidak suka komentar arogan / lucu (terutama jika mereka termasuk bersumpah) - mungkin sedikit lucu saat pertama kali Anda membacanya tetapi menjadi sangat tua (dan karenanya mengganggu) dengan sangat cepat.
FinnNk
5
Saya suka contoh Anda, meskipun saya akan mengatakan bahwa dalam konteks tertentu, beberapa bersarang jika pernyataan tidak dapat dihindari. Dengan banyak logika bisnis, kode dapat sedikit membingungkan, tetapi jika bisnis itu sendiri membingungkan untuk memulai, untuk menyederhanakan kode akan menjadi model proses yang kurang akurat. Seperti yang dikatakan Einstein: "Segala sesuatunya harus sesederhana mungkin dan tidak sedikit lebih sederhana."
Morgan Herlocker
2
@Prof Plum - Contoh apa yang dapat Anda berikan? Biasanya alternatif untuk multiple nested jika untuk memecahnya menjadi (banyak) metode. Pengembang junior cenderung menghindari ini seolah-olah itu kurang diinginkan daripada jika; tetapi biasanya ketika ditekan mereka mengatakan "jika melakukannya dalam lebih sedikit garis". Dibutuhkan seseorang yang percaya diri dalam OOP untuk masuk dan mengingatkan mereka bahwa lebih sedikit baris! = Kode yang lebih baik.
STW
2
@STW Itu poin yang bagus, namun, saya akan mengatakan bahwa itu tergantung seberapa dalam sarangnya. Saya pasti akan setuju bahwa kedalaman lebih dari tiga sarang sering membutuhkan refactoring, karena itu akan menjadi sangat berbulu. Mengutip asuransi, adalah contoh yang baik di mana multi-nesting sebenarnya dapat memodelkan dunia nyata dengan cukup baik. Dengan pengecualian untuk tarif / premi tertentu, manual ini akan secara harfiah membaca sesuatu seperti "jika ini adalah properti dan jika memiliki tingkat minimum di bawah 5,6 dan jika berada di NC dan jika memiliki kapal di lokasi, maka lakukan itu dan seperti itu." dengan banyak opsi lain.
Morgan Herlocker
4
@ Astaga, jika "mereka" adalah kolega maka saya akan merenungkan mengapa Anda tidak mengatakan "kami" ...
104

Bendera merah utama bagi saya adalah blok kode duplikat, karena itu menunjukkan bahwa orang tersebut tidak memahami dasar-dasar pemrograman atau terlalu takut untuk membuat perubahan yang tepat ke basis kode yang ada.

Saya dulu juga menghitung kurangnya komentar sebagai bendera merah, tetapi setelah baru-baru ini bekerja pada banyak kode yang sangat baik tanpa komentar saya sudah mereda kembali pada itu.

Ben Hughes
sumber
1
+1: Saya melihat beberapa kode dari kolega yang disebut-sebut sebagai pakar linux, yang menulis aplikasi perulangan sederhana sebagai satu fungsi panjang, semuanya berulang-ulang di main (). Astaga.
KFro
4
@KFro, itu loop membuka gulungan. Thats what compiler lakukan sepanjang waktu :) SANGAT efisien!
3
@ Talbjorn: Terkadang, Anda harus sedikit membantu kompiler; Bagaimanapun, Anda adalah manusia yang cerdas dan ia hanyalah komputer yang bodoh.
yatima2975
3
Alasan lain yang saya lihat: konsultan dibayar untuk mengimplementasikan fitur secepat mungkin (itu sebabnya tes dan dokumentasi juga hilang, tentu saja). Menyalin / menempel lebih cepat daripada memikirkan cara melakukan sesuatu dengan benar.
LennyProgrammers
4
Menghindari duplikasi kode bisa menjadi obsesi. Dalam bahasa seperti C ++, itu tidak selalu semudah seharusnya mempertimbangkan faktor bagian yang berbeda namun masih memiliki kode yang kuat dan efisien. Terkadang, sedikit potong-dan-tempel adalah pilihan yang lebih praktis. Juga, prinsip optimasi dapat diterapkan - cut-and-paste dapat memberi Anda solusi cepat dan mudah yang dapat Anda refactor nanti jika diperlukan. Anda mungkin menyimpan sakit kepala pemeliharaan untuk nanti, tetapi Anda tahu pasti bahwa Anda menghindari penundaan saat ini.
Steve314
74

Kode yang mencoba menunjukkan betapa pandai programmer adalah, terlepas dari kenyataan bahwa itu tidak menambah nilai nyata:

x ^= y ^= x ^= y;
Rei Miyasaka
sumber
12
Wow, itu sooo jauh lebih mudah dibaca daripadaswap(x, y);
JBRWilkinson
8
jika x dan y adalah pointer, dan penugasan ini berlangsung dalam jangka waktu yang cukup lama, itu akan menghancurkan pengumpul sampah konservatif seperti Boehm GC.
SingleNegationElimination
12
Ngomong-ngomong, kode ini tidak terdefinisi dalam C dan C ++ karena beberapa perubahan tanpa titik urutan intervensi.
fredoverflow
9
Melihat itu, satu-satunya hal yang terlintas dalam pikiran adalah emotikon:^_^
Darien
62
  • 20.000 fungsi garis (berlebihan). Setiap fungsi yang membutuhkan lebih dari beberapa layar perlu di-factoring ulang.

  • Sepanjang baris yang sama, file kelas yang sepertinya berlangsung selamanya. Mungkin ada beberapa konsep yang dapat diabstraksi menjadi kelas-kelas yang akan menjernihkan tujuan dan fungsi kelas asli, dan mungkin di mana ia digunakan, kecuali mereka semua adalah metode internal.

  • variabel non-deskriptif, non-trivial, atau terlalu banyak variabel non-deskriptif sepele. Ini membuat menyimpulkan apa yang sebenarnya terjadi teka-teki.

Dominique McDonnell
sumber
9
Saya cenderung membatasi fungsi menjadi 1 layar bila memungkinkan.
Matt DiTrolio
20
1 layar bahkan panjang. Saya mulai merasa kotor setelah 10 atau lebih baris.
Bryan Rowe
54
Oke, saya akan menyuarakan pendapat yang mungkin tidak populer. Saya katakan kode bau untuk menulis fungsi yang atom, proses top-to-bottom yang dipecah menjadi fungsi terpisah karena pengembang melekat pada beberapa "fungsi harus pendek" kargo-kultus. Fungsi harus dipatahkan sepanjang garis FUNGSIONAL, bukan hanya karena mereka harus menjadi "ukuran yang tepat" mitos. Itu sebabnya mereka disebut FUNGSI.
Dan Ray
7
@Dan, Fungsi tidak boleh pendek demi menjadi pendek, tetapi hanya ada begitu banyak info yang dapat Anda simpan di kepala Anda sekaligus. Mungkin saya punya otak kecil karena bagi saya batasnya adalah beberapa layar :). Memecah fungsi menjadi beberapa fungsi ketika mereka mulai menguji batas yang diperlukan untuk menghindari kesalahan. Di satu sisi ia menyediakan enkapsulasi sehingga Anda dapat berpikir pada tingkat yang lebih tinggi dan di sisi lain ia menyembunyikan apa yang terjadi sehingga mempersulit untuk mengetahui bagaimana fungsi itu bekerja. Saya pikir bahwa memecah fungsi harus dilakukan untuk membantu keterbacaan, bukan untuk memenuhi 'panjang sempurna'.
Dominique McDonnell
6
@ Dominic, @ Péter, saya pikir kita bertiga sebenarnya mengatakan hal yang sama. Ketika ada alasan bagus untuk memasukkan kode ke dalam fungsi yang lebih kecil, saya akan melakukannya. Apa yang saya tolak adalah kependekan demi kependekan dalam desain fungsi. Anda tahu, tumpukan panggilan itu tiga kali lebih lama dari yang seharusnya, tetapi setidaknya fungsi-fungsi itu pendek. Saya lebih suka men-debug fungsi tinggi yang melakukan satu hal dengan baik dan jelas daripada mengejar jalur eksekusi melalui selusin fungsi berantai yang masing-masing hanya dipanggil dari yang sebelumnya.
Dan Ray
61
{ Let it Leak, people have good enough computers to cope these days }

Yang lebih parah adalah itu dari perpustakaan komersial!

Sangat etis
sumber
32
Ini tidak membunyikan bel alarm. Praktis menendang Anda di antara kedua kaki.
Steven Evers
15
Anak perempuan adalah pecandu met. Siapa peduli, setidaknya dia tidak akan menjadi gemuk. :: sigh ::
Evan Plaice
17
Ketika saya menemukan diri saya dalam masa-masa sulit, ibu buntu mendatangi saya. Berbicara kata-kata bijak, biarkan bocor. LET IT Leak .. LET IT Leak. BIARKAN KEBOCORAN oh BIARKAN KEBOCORAN. Jika hanya bocor satu kali, itu bukan leaaaaaak. (jika Anda membaca sejauh ini, +1). Saya benar-benar perlu mempertimbangkan kopi tanpa kafein.
Tim Post
13
"Ketika tenggat waktu semakin dekat, LEAKS adalah yang dapat saya lihat, di suatu tempat seseorang berbisik, 'Tulis di C ...... eeeeee !!!'"
chiurox
9
Alkisah ada dua OS. Satu bocor dan jatuh jika berjalan lebih dari 49 hari, yang lain sempurna dan akan berjalan selamanya. Satu diluncurkan pada 1995 ke sebuah pesta besar dan digunakan oleh jutaan orang - yang lain tidak pernah dikirim karena mereka masih memeriksa bahwa itu bebas bug. Ada perbedaan antara filsafat dan teknik.
Martin Beckett
53

Komentar yang sangat verbose bahwa jika ada kompiler bahasa Inggris, itu akan mengkompilasi dan berjalan dengan sempurna, namun tidak menggambarkan apa pun yang kode tidak.

//Copy the value of y to temp.
temp = y;
//Copy the value of x to y.
y = x;
//Copy the value of temp to x.
x = temp;

Juga, komentar pada kode yang bisa dihapuskan seandainya kode tersebut mematuhi beberapa pedoman dasar:

//Set the age of the user to 13.
a = 13;
Rei Miyasaka
sumber
15
Ada, namanya COBOL :-)
Gayus
26
Kasus kedua bukan yang terburuk. Yang terburuk adalah: / * Atur usia pengguna menjadi 13 * / a = 18;
PhiLho
4
@ Philho - tidak, bahkan lebih buruk adalah ketika /dari yang */hilang, sehingga semua kode ke akhir selanjutnya */diabaikan. Untungnya, penyorotan sintaksis membuat hal semacam itu jarang terjadi akhir-akhir ini.
Steve314
3
Lebih buruk lagi, auntuk user_age? Benarkah?
glasnt
2
Saya biasa memelihara dokumen standar kode pada pemberi kerja sebelumnya, salah satu bagiannya memberikan komentar yang sesuai. Contoh favorit saya adalah dari MSDN:i = i + 1; //increment i
Michael Itzoe
42

Kode yang menghasilkan peringatan saat dikompilasi.

Rei Miyasaka
sumber
1
Ada kandidat untuk menambahkan opsi kompilasi 'Semua peringatan sebagai Kesalahan' ke makefile / proyek.
JBRWilkinson
3
Saya kira itu bisa berguna jika Anda berada dalam sebuah proyek dengan banyak orang yang tidak Anda percayai - meskipun jika saya bergabung dengan sebuah proyek di mana opsi itu ditetapkan, itu sendiri akan membuat saya khawatir tentang bagaimana bisa yang lain programmer adalah.
Rei Miyasaka
1
Saya tidak setuju dengan ini. Beberapa peringatan kompiler (seperti perbandingan antara yang ditandatangani dan yang tidak ditandatangani, ketika Anda tahu kedua nilai tersebut tidak ditandatangani, meskipun jenisnya berbeda) lebih disukai daripada membuang sampah sembarangan kode dengan gips yang tidak perlu. Jika saya mengurangi kode dengan menggunakan integer bertanda tangan portabel yang fungsi memodifikasi hanya jika integer memiliki nilai yang tidak ditandatangani, saya akan melakukannya.
Tim Post
13
Saya lebih suka mengacaukan kode saya dengan daftar yang hampir tidak berguna (unsigned int)daripada mengacaukan daftar peringatan / kesalahan saya dengan peringatan yang tidak berbahaya. Aku benci daftar peringatan menjadi titik buta. Ini juga jauh lebih dari PITA menjelaskan kepada orang lain mengapa Anda mengabaikan peringatan daripada untuk menjelaskan mengapa Anda melakukan cast alami intsuntuk unsigned ints.
Rei Miyasaka
Terkadang, Anda harus bekerja dengan API yang menghasilkan kesalahan apa pun yang Anda lakukan. Contoh klasik adalah di mana API didefinisikan dalam hal hal-hal yang rusak oleh desain (beberapa konstanta ioctl () lama seperti itu, dan kadang-kadang pengembang OS bersikeras menggunakan jenis yang salah di header mereka) atau di mana mereka telah menghentikan sesuatu tanpa meninggalkan pengganti yang baik (terima kasih, Apple).
Donal Fellows
36

Berfungsi dengan angka dalam nama alih-alih memiliki nama deskriptif , seperti:

void doSomething()
{
}

void doSomething2()
{
}

Tolong, buat nama fungsi berarti sesuatu! Jika doSomething dan doSomething2 melakukan hal serupa, gunakan nama fungsi yang membedakan perbedaan. Jika doSomething2 adalah pelarian fungsionalitas dari doSomething, beri nama untuk fungsionalitasnya.

Wonko the Sane
sumber
Demikian juga @Parm untuk SQL
Dave
2
+1 - Masuk mshtml- mataku hancur :(
Kyle Rozendo
3
Pengecualian untuk ini adalah kode GUI. Misalnya, jika formulir surat siput memiliki dua alamat; address1 dan address2 lebih masuk akal daripada address dan alternateAddress. Label palsu yang hanya statis juga merupakan pengecualian yang masuk akal.
Evan Plaice
@Van - cukup adil, meskipun saya lebih membuat perbedaan dalam fungsionalitas.
Wonko the Sane
1
+1 - Saya bahkan pernah melihat ini digunakan sebagai metode kontrol versi semu.
EZ Hart
36

Angka Ajaib atau String Ajaib.

   if (accountBalance>200) { sendInvoice(...); }

   salesPrice *= 0.9;   //apply discount    

   if (invoiceStatus=="Overdue") { reportToCreditAgency(); }
JohnFx
sumber
4
Tidak terlalu buruk dengan dua yang kedua, setidaknya diskon dijelaskan, dan "Ditunggu" adalah intuitif. Di 200sisi lain ...
Tarka
9
@Lokun - Intuitif bukan intinya pemeliharaan dan kerapuhan. Misalnya, perhatikan apa yang terjadi ketika jumlah diskon berubah dan 0,9 di-kode-keras di enam tempat berbeda. Juga, menggunakan string bukan konstanta / enum meminta masalah dalam bahasa dengan string case sensitif.
JohnFx
+1 Saya hanya menghabiskan terlalu banyak waktu men-debug masalah yang ternyata disebabkan oleh garis 'batas waktu = 15;' dimakamkan dalam suatu program.
aubreyrhodes
Saya pikir yang terakhir kadang - kadang baik - baik saja, tergantung dari mana data untuk invoiceStatus berasal. Jika itu hanya datang dari api publik yang mengembalikan JSON yang baru saja diterjemahkan, memeriksa terhadap konstanta String hard-coded mungkin baik-baik saja. Setuju bahwa "200" dan "0,9" hanyalah konstanta ajaib dan tidak boleh dikodekan dengan cara ini. Bahkan jika mereka hanya digunakan di satu tempat ini, pemeliharaan lebih mudah jika Anda mendefinisikannya di bagian konfigurasi secara terpisah daripada memotongnya dalam kode logika. Dan jika digunakan di banyak tempat, perawatan menjadi lebih mudah.
Ben Lee
36
  • Mungkin bukan yang terburuk tetapi jelas menunjukkan tingkat pelaksana:

    if(something == true) 
  • Jika suatu bahasa memiliki for for atau iterator construct, maka menggunakan while sementara juga menunjukkan tingkat pemahaman pelaksana bahasa:

    count = 0; 
    while(count < items.size()){
       do stuff
       count ++; 
    }
    
    for(i = 0; i < items.size(); i++){
      do stuff 
    }
    //Sure this is not terrible but use the language the way it was meant to be used.
    
  • Ejaan / tata bahasa yang buruk dalam dokumentasi / komentar memakan saya hampir sebanyak kode itu sendiri. Alasan untuk ini adalah karena kode dimaksudkan untuk dibaca manusia dan mesin dijalankan. Inilah sebabnya kami menggunakan bahasa tingkat tinggi, jika dokumentasi Anda sulit untuk menembusnya membuat saya lebih dulu membentuk opini negatif tentang basis kode tanpa melihatnya.

Chris
sumber
29

Yang saya perhatikan segera adalah frekuensi blok kode yang sangat bersarang (jika, sementara, dll). Jika kode sering lebih dari dua atau tiga level, itu pertanda masalah desain / logika. Dan jika kedalamannya mencapai 8 sarang, lebih baik ada alasan kuat untuk tidak putus.

GrandmasterB
sumber
6
Saya tahu beberapa orang belajar bahwa setiap metode seharusnya hanya memiliki satu returnpernyataan, tetapi ketika itu menyebabkan tingkat 6 + jika bersarang saya pikir itu melakukan jauh lebih berbahaya daripada yang baik.
Darien
28

Saat menilai program siswa, kadang-kadang aku bisa mengatakannya dengan gaya "blink". Ini adalah petunjuk instan:

  • Pemformatan buruk atau tidak konsisten
  • Lebih dari dua baris kosong berturut-turut
  • Konvensi pemberian nama yang tidak standar atau tidak konsisten
  • Kode berulang, semakin kata demi kata berulang, semakin kuat peringatan
  • Apa yang seharusnya menjadi potongan kode sederhana terlalu rumit (misalnya, memeriksa argumen yang diteruskan ke utama dengan cara yang berbelit-belit)

Jarang kesan pertama saya salah, dan lonceng peringatan ini benar sekitar 95% . Untuk satu pengecualian, seorang siswa baru ke bahasa itu menggunakan gaya dari bahasa pemrograman yang berbeda. Menggali dan membaca ulang gaya mereka dalam idiom bahasa lain menghilangkan bel alarm untuk saya, dan siswa kemudian mendapat pujian penuh. Tetapi pengecualian seperti itu jarang terjadi.

Saat mempertimbangkan kode lebih lanjut, ini adalah peringatan saya yang lain:

  • Kehadiran banyak kelas Java yang hanya "struct" untuk menyimpan data. Tidak masalah jika bidangnya publik atau pribadi dan menggunakan getter / setter, itu masih mungkin bukan bagian dari desain yang dipikirkan dengan matang.
  • Kelas yang memiliki nama yang buruk, seperti hanya menjadi namespace dan tidak ada kohesi yang nyata dalam kode
  • Referensi pola desain yang bahkan tidak digunakan dalam kode
  • Penangan pengecualian kosong tanpa penjelasan
  • Ketika saya menarik kode di Eclipse, ratusan "peringatan" garis kuning kode, sebagian besar karena impor atau variabel yang tidak digunakan

Dalam hal gaya, saya biasanya tidak suka melihat:

  • Komentar Javadoc yang hanya mengulangi kode

Ini hanya petunjuk kode yang buruk. Kadang-kadang apa yang tampak seperti kode buruk sebenarnya tidak, karena Anda tidak tahu niat programmer. Misalnya, mungkin ada alasan bagus bahwa sesuatu tampak terlalu rumit - mungkin ada pertimbangan lain yang berperan.

Macneil
sumber
Saya gagal melihat bagaimana menggunakan gaya dari satu bahasa ke bahasa lain adalah kesalahan yang menyedihkan (2, 4, 8 spasi per indent ...). Jika siswa memiliki sedikit gaya lain untuk diikuti, tidak ada yang salah dengan menjadi mandiri. Sebagai siswa kelas Anda melihat satu miliar program sehingga Anda berada di ujung spektrum itu, tetapi itu bukan alasan untuk benar-benar mengabaikan gaya yang berbeda (tapi konsisten).
Nick T
18
Saya melihat tidak ada yang salah dengan kelas yang hanya mengumpulkan data - yaitu, struct. Itulah Data Transfer Objects (DTOs) dan dapat membuat kode jauh lebih mudah dibaca daripada mengatakan, misalnya memasukkan 20 parameter ke suatu metode.
Nemi
1
Komentar Anda tentang struct sudah tepat. Tidak apa-apa ketika data dalam bentuk paling mentah dan tidak akan dimodifikasi dengan cara apa pun. Tetapi 95% dari waktu Anda harus memiliki beberapa fungsi di kelas untuk memformat / beroperasi pada data. Saya baru ingat beberapa kode saya yang pada dasarnya menggunakan pola itu dan harus diperbaiki.
DisgruntledGoat
2
+1 untuk gaya yang tidak konsisten dan jeda baris tambahan (saya telah melihat lekukan acak, tidak ada lekukan, konvensi penamaan acak dan perubahan, dan lainnya - dan ini dalam kode produksi!). Jika Anda bahkan tidak bisa repot-repot memperbaikinya, lalu apa lagi yang bisa Anda lakukan?
Dean Harding
1
Saya mencari garis deklarasi metode yang indentasi terlalu jauh relatif terhadap tubuh. Ini adalah tanda yang mereka salin dan tempel dari file orang lain.
Barry Brown
25

Favorit pribadi / kesayangan hewan peliharaan: Nama yang dihasilkan IDE yang dapat dikirim. Jika TextBox1 adalah variabel utama dan penting dalam sistem Anda, Anda punya hal lain yang datang ulasan kode.

Wyatt Barnett
sumber
25

Variabel yang sama sekali tidak digunakan , terutama ketika variabel tersebut memiliki nama yang mirip dengan nama variabel yang digunakan.

C. Ross
sumber
21

Banyak orang menyebutkan:

//TODO: [something not implemented]

Sementara saya berharap hal-hal itu dilaksanakan, setidaknya mereka membuat catatan. Yang saya pikir lebih buruk adalah:

//TODO: [something that is already implemented]

Todo tidak berharga dan membingungkan jika Anda tidak pernah repot-repot menghapusnya!

Morgan Herlocker
sumber
1
Saya baru saja melalui latihan karena harus membuat laporan dari semua TODO dalam produk rilis kami, ditambah rencana untuk mendepositkannya. Hampir setengah berubah menjadi usang.
AShelly
1
-1 Komentar TODO digunakan dalam MS Visual Studio untuk melacak bagian-bagian dari proyek yang masih perlu dikerjakan. IE, IDE menyimpan daftar yang melacak TODO sehingga Anda dapat dengan mudah mengkliknya dan dibawa langsung ke baris tempat TODO ada. Saya lebih suka melihat TODO ditempatkan secara eksplisit untuk melihat pekerjaan apa yang masih perlu dilakukan. Lihat dotnetperls.com/todo .
Evan Plaice
3
@Van Plaice: Wow, maksud Anda VS IDE mengenali ketika Anda menerapkan sesuatu dan menghapus //TODOkomentar? Luar biasa!
JBRWilkinson
4
@Prof Plum Mengapa tidak hanya membuat kebijakan di mana orang yang bertanggung jawab atas TODO menuliskan nama mereka di komentar. Dengan begitu, jika ada beberapa sisa makanan itu
Evan Plaice
3
Rencana yang lebih baik daripada // TODO , gunakan pelacak bug Anda, untuk itulah!
SingleNegationElimination
20

Metode yang mengharuskan saya untuk menggulir ke bawah untuk membaca semuanya.

BradB
sumber
14
Hmm .. ini tergantung apa yang sedang diimplementasikan. Ini tidak masuk akal untuk ini terjadi ketika menerapkan beberapa algoritma yang rumit, karena itulah bagaimana mereka didefinisikan. Tentu saja, jika mayoritas metode seperti itu, itu adalah bendera merah.
Billy ONeal
9
Sebagai pernyataan selimut maka saya tidak setuju, buang-buang waktu terus-menerus refactoring sehingga semuanya sesuai dengan aturan yang dipaksakan sendiri ini benar-benar meningkatkan biaya keseluruhan proyek.
Jenis Anonim
1
Saya tidak setuju bahwa aturan ini dapat meningkatkan biaya keseluruhan proyek tetapi saya kira itu subjektif karena akan tergantung pada pengembang (s). Jika Anda tetap berpegang pada prinsip umum "pemisahan kepedulian" sementara mengembangkan maka re-factoring akan kurang dari tugas jika seseorang memilih untuk melakukannya. Sesuatu yang perlu dipertimbangkan adalah berapa biayanya tiga tahun ke depan ketika pengembang yang tidak membuat kode proyek asli mencoba untuk bug memperbaiki banyak metode dengan 300 + baris kode? Berapa harganya?
BradB
18
Saya lebih jengkel saat menggulir ke kanan daripada saat menggulir ke bawah. Spasi adalah "gratis."
Wonko the Sane
4
Saya lebih suka menggulir daripada harus melewati seluruh file (atau beberapa file) untuk mengetahui apa yang dilakukan kode.
TMN
20

Konjungsi dalam nama metode:

public void addEmployeeAndUpdatePayrate(...) 


public int getSalaryOrHourlyPay(int Employee) ....

Klarifikasi: Alasan mengapa alarm berbunyi adalah karena ini mengindikasikan metode yang kemungkinan melanggar prinsip tanggung jawab tunggal .

JohnFx
sumber
Hmmm ... jika nama fungsi secara akurat mendefinisikan apa fungsi tidak, maka saya tidak setuju. Jika metode ini melakukan dua hal terpisah yang akan lebih baik untuk dipisahkan, maka saya mungkin setuju, tergantung pada konteksnya.
Wonko the Sane
2
Itulah intinya. Konjungsi menyiratkan bahwa sangat mungkin ia melakukan lebih dari satu hal. Per pertanyaan itu hanya sesuatu yang meningkatkan kesadaran saya bahwa ada sesuatu yang salah.
JohnFx
3
Sekarang bagaimana jika Anda harus menambah karyawan dan memperbarui jumlah pembayaran mereka di beberapa tempat? Jika metode itu berisi dua panggilan metode ( addEmployee(); updatePayrate();), maka saya tidak berpikir itu masalah.
Matt Grande
13

Menghubungkan kode sumber yang jelas GPL ke dalam program komersial, sumber tertutup.

Tidak hanya membuat masalah hukum langsung, tetapi dalam pengalaman saya, biasanya menunjukkan baik kecerobohan atau tidak peduli yang tercermin di tempat lain dalam kode juga.

Bob Murphy
sumber
6
Meskipun poin Anda sangat bagus, nada suara Anda tidak perlu.
JBRWilkinson
@ JBRWilkinson: Terima kasih, Anda benar. Permintaan maaf saya untuk semua
Bob Murphy
Saya pikir judul Anda perlu ditulis ulang. Baik tautan statis dan dinamis ke kode sumber GPL adalah pelanggaran terhadap GPL ...
Gavin Coates
Poin bagus. Saya telah menulis ulang seluruh pos. Terimakasih untuk semua.
Bob Murphy
9

Bahasa agnostik:

  • TODO: not implemented
  • int function(...) { return -1; } (sama dengan "tidak diterapkan")
  • Melempar pengecualian karena alasan yang tidak biasa.
  • Penyalahgunaan atau penggunaan yang tidak konsisten 0, -1atau nullsebagai nilai pengembalian yang luar biasa.
  • Pernyataan tanpa komentar meyakinkan yang mengatakan mengapa itu tidak boleh gagal.

Khusus bahasa (C ++):

  • C ++ Macro dalam huruf kecil.
  • Variabel C ++ Statis atau Global.
  • Variabel tidak diinisialisasi atau tidak digunakan.
  • Apa pun array newyang tampaknya tidak aman RAII.
  • Setiap penggunaan array atau pointer yang tampaknya tidak aman-batas. Ini termasuk printf.
  • Setiap penggunaan bagian array yang tidak diinisialisasi.

Khusus Microsoft C ++:

  • Setiap nama pengidentifikasi yang berbenturan dengan makro sudah ditentukan oleh salah satu file header Microsoft SDK.
  • Secara umum, setiap penggunaan Win32 API adalah sumber lonceng alarm yang besar. Selalu minta MSDN terbuka, dan cari argumen / definisi kembali nilai setiap kali ragu. (Diedit)

Khusus C ++ / OOP:

  • Warisan implementasi (kelas konkret) di mana kelas induk memiliki metode virtual dan non-virtual, tanpa perbedaan konseptual yang jelas antara apa yang seharusnya / tidak boleh virtual.
rwong
sumber
18
// TODO: Komentari jawaban ini
johnc
8
Saya kira "bahasa agnostik" berarti "C / C ++ / Java" sekarang?
Inaimathi
+1 "Melempar pengecualian untuk alasan yang tidak biasa" tidak bisa setuju lebih banyak!
billy.bob
2
@Inaimathi - Komentar TODO, fungsi bertopik, penyalahgunaan pengecualian, kebingungan semantik nol / nol / kosong dan cek kewarasan tak berguna melekat pada semua bahasa imperatif / OOP dan sampai batas tertentu semua bahasa pemrograman pada umumnya.
Rei Miyasaka
Saya percaya bahwa macro preprocessor C dalam huruf kecil tidak apa - apa, tetapi hanya jika mereka mengevaluasi argumen mereka hanya sekali dan menghasilkan hanya satu pernyataan.
Joe D
8

Gaya lekukan yang aneh.

Ada beberapa gaya yang sangat populer, dan orang-orang akan membawa perdebatan itu ke kubur. Tetapi kadang-kadang saya melihat seseorang menggunakan gaya lekukan yang benar-benar langka, atau bahkan buatan sendiri. Ini adalah tanda bahwa mereka mungkin belum mengkodekan dengan orang lain selain diri mereka sendiri.

Ken
sumber
2
atau hanya tanda bahwa mereka adalah talenta individualistis yang sangat berharga yang belum terperangkap dalam jaringan praktik pengkodean yang dihomogenisasi yang sama sekali tidak terkait dengan "praktik terbaik".
Jenis Anonim
1
Saya harap Anda menjadi sarkastik. Jika seseorang melakukan pengkodean dengan cara yang tidak biasa, itu akan mematikan alarm. Mereka bisa menjadi artistik seperti yang mereka inginkan, tetapi masih ... lonceng alarm.
Ken
2
Ada gaya yang agak tidak biasa (saya percaya itu disebut gaya Utrecht) yang saya temukan cukup berguna meskipun sangat jarang di luar Haskell / ML / F #. Gulir ke bawah ke "Bentuk modul": learnyouahaskell.com/making-our-own-types-and-typeclasses . Apa yang baik tentang gaya ini adalah bahwa Anda tidak perlu memodifikasi pembatas pada baris sebelumnya untuk menambahkan yang baru - yang sering saya lupa lakukan.
Rei Miyasaka
@ReiMiyasaka Tujuh tahun terlambat, tapi ... Gaya Utrecht benar-benar membuatku jengkel. Saya percaya bahwa ini adalah kesalahan dalam spesifikasi Haskell untuk tidak memaksakan "aturan tata letak" yang lain pada daftar yang diatur secara vertikal. Dengan begitu, pengurai dapat mendeteksi entri daftar baru hanya dengan memeriksa lekukan, yang merupakan cara setiap orang mengatur daftar mereka.
Ryan Reich
@RyanReich Aneh, tujuh tahun kemudian, dan saya masih menyukainya. Namun saya setuju; untuk semua kecanggungan dan kegagalan sintaksisnya, F # juga memungkinkan item dibatasi hanya oleh baris baru dan lekukan (dalam kebanyakan kasus), yang membuat kode rapi.
Rei Miyasaka
8

Menggunakan banyak blok teks daripada enum atau variabel yang didefinisikan secara global.

Tidak baik:

if (itemType == "Student") { ... }

Lebih baik:

private enum itemTypeEnum {
  Student,
  Teacher
}
if (itemType == itemTypeEnum.Student.ToString()) { ... }

Terbaik:

private itemTypeEnum itemType;
...
if (itemType == itemTypeEnum.Student) { ... }
Yaakov Ellis
sumber
Atau yang terbaik: Gunakan polimorfisme.
Lstor
8

Parameter yang diketik dengan lemah atau mengembalikan nilai pada metode.

public DataTable GetEmployees() {...}

public DateTime getHireDate(DataTable EmployeeInfo) {...}

public void FireEmployee(Object EmployeeObjectOrEmployeeID) {...}
JohnFx
sumber
2
+1: Saya harus bekerja dengan beberapa layanan web "REST" yang mengembalikan semuanya sebagai tabel pseudo-HTML, bahkan ketika Anda menyampaikan hal-hal yang merupakan kesalahan sintaksis yang jelas. Tidak diizinkan? Masukkan sampah lengkap? Server melebihi kapasitas? 200 (ditambah pesan dalam format mengerikan dalam satu kolom, satu tabel baris). AAaaaaaaaargh!
Donal Fellows
7
  • Beberapa operator ternary dirangkai, jadi alih-alih menyerupai if...elseblok, itu menjadi if...else if...[...]...elseblok
  • Nama variabel panjang tanpa garis bawah atau CamelCasing. Contoh dari beberapa kode yang saya ambil:$lesseeloginaccountservice
  • Ratusan baris kode dalam file, dengan sedikit atau tidak ada komentar, dan kode menjadi sangat tidak jelas
  • ifPernyataan yang terlalu rumit . Contoh dari kode: if (!($lessee_obj instanceof Lessee && $lessee_obj != NULL))yang saya gunakan untuk chompedif ($lessee_obj == null)
Tarka
sumber
7

Kode bau: tidak mengikuti praktik terbaik

Hal semacam ini selalu membuat saya khawatir karena ada disangkal bahwa semua orang berpikir mereka adalah pengemudi di atas rata-rata.

Inilah kilasan berita untuk Anda: 50% dari populasi dunia di bawah rata-rata intelijen. Ok, jadi beberapa orang akan memiliki kecerdasan rata-rata, tapi jangan pilih-pilih Juga, salah satu sisi yang mempengaruhi kebodohan adalah Anda tidak bisa mengenali kebodohan Anda sendiri! Hal-hal tidak terlihat begitu baik jika Anda menggabungkan pernyataan ini.

Hal-hal mana yang langsung membunyikan lonceng alarm ketika melihat kode?

Banyak hal baik telah disebutkan, dan secara umum tampaknya tidak mengikuti praktik terbaik adalah bau kode.

Praktik terbaik biasanya tidak ditemukan secara acak, dan sering ada karena suatu alasan. Sering kali itu bisa subjektif, tetapi dalam pengalaman saya kebanyakan dibenarkan. Mengikuti praktik terbaik seharusnya tidak menjadi masalah, dan jika Anda bertanya-tanya mengapa hal itu terjadi, teliti daripada mengabaikan dan / atau mengeluh tentang hal itu - mungkin itu dibenarkan, mungkin tidak.

Salah satu contoh praktik terbaik mungkin menggunakan ikal dengan setiap blok jika, meskipun hanya berisi satu baris:

if (something) {
    // whatever
}

Anda mungkin tidak berpikir itu perlu, tetapi saya baru-baru ini membaca bahwa itu adalah sumber utama bug. Selalu menggunakan tanda kurung juga telah dibahas pada Stack Overflow , dan memeriksa bahwa jika pernyataan memiliki tanda kurung juga merupakan aturan dalam PMD , penganalisa kode statis untuk Java.

Ingat: "Karena ini praktik terbaik" tidak pernah merupakan jawaban yang dapat diterima untuk pertanyaan "mengapa Anda melakukan ini?" Jika Anda tidak dapat mengartikulasikan mengapa sesuatu itu praktik terbaik, maka itu bukan praktik terbaik, itu takhayul.

Vetle
sumber
2
Ini mungkin luar biasa, tapi saya pikir itu penting apa yang Anda pilih rata-rata Seperti yang saya pahami, 50% populasi dunia berada di bawah kecerdasan median (menurut definisi); tetapi rata-rata lainnya tidak bekerja dengan cara yang sama. Misalnya, ambil populasi (1, 1, 1, 5) yang memiliki rata-rata aritmatika 2.
flamingpenguin
ummm, Anda mengutip tulisan "what-superstitions-do-programmer-have" di mana pengguna membuat pernyataan berani tentang kurung kurawal tanpa sumber. Saya tidak melihat itu sebagai contoh yang baik dari praktik terbaik.
Evan Plaice
@ Evan: ya, Anda benar. Saya menambahkan sedikit tentang itu, semoga ini membantu.
Vetle
4
Kebalikan dari ini adalah orang-orang yang dengan kasar mengikuti "praktik terbaik" tanpa pemikiran kritis mengapa sesuatu adalah "praktik terbaik". Inilah mengapa saya sangat tidak menyukai istilah "praktik terbaik", karena bagi sebagian orang itu adalah alasan untuk berhenti berpikir dan mengikuti kawanan. "Karena ini praktik terbaik" tidak pernah merupakan jawaban yang dapat diterima untuk pertanyaan "mengapa kamu melakukan ini?" Jika Anda tidak dapat mengartikulasikan mengapa sesuatu itu praktik terbaik, maka itu bukan praktik terbaik, itu takhayul.
Dan Dyer
Komentar yang sangat bagus, Dan! Saya menambahkan dua baris terakhir ke jawabannya.
Vetle
6

Komentar yang mengatakan "ini karena desain dari subsistem froz benar-benar borked."

Itu berlangsung lebih dari satu paragraf penuh.

Mereka menjelaskan bahwa refactor berikut perlu terjadi.

Tetapi tidak melakukannya.

Sekarang, mereka mungkin telah diberitahu bahwa mereka tidak dapat mengubahnya oleh bos mereka pada saat itu, karena masalah waktu atau kompetensi, tetapi mungkin itu karena orang-orang yang picik.

Jika seorang penyelia berpikir j.random itu. Programmer tidak dapat melakukan refactoring, maka supervisor harus melakukannya.

Bagaimanapun ini terjadi, saya tahu kode ini ditulis oleh tim yang terbagi, dengan kemungkinan politik kekuasaan, dan mereka tidak memperbaiki desain subsistem yang tidak jelas.

Kisah nyata. Itu bisa saja terjadi padamu.

Tim Williscroft
sumber
6

Adakah yang bisa memikirkan contoh di mana kode harus secara sah merujuk ke file dengan jalur absolut?

Rei Miyasaka
sumber
1
Jumlah skema XML?
Nick T
1
File konfigurasi sistem. Biasanya harus ditetapkan oleh ./configure, tetapi bahkan itu membutuhkan nilai default di suatu tempat.
eswald
4
/dev/nulldan teman baik-baik saja. Tetapi bahkan hal-hal seperti /bin/bashitu dicurigai - bagaimana jika Anda salah satu sistem kooky yang dimiliki /usr/bin/bash?
Tom Anderson
1
Kode klien layanan web yang dihasilkan oleh alat JAX-WS (JBossWS dan Metro, setidaknya) berisi jalur absolut bawaan untuk file WSDL (dua kali!). Mungkin ini sesuatu yang sangat tidak pantas /home/tom/dev/randomhacking/thing.wsdl. Hal ini kriminal gila bahwa ini adalah perilaku default.
Tom Anderson
4
tentang /dev/null: Saya punya kebiasaan, ketika mengembangkan di windows untuk menjaga aplikasi dan libs di bawah c:\dev. Entah bagaimana, folder nullselalu dibuat secara otomatis di dalam folder itu. Aku bersumpah aku tidak tahu siapa yang melakukan itu. (Salah satu bug / fitur favorit saya)
Sean Patrick Floyd
6

Menangkap pengecualian umum:

try {

 ...

} catch {
}

atau

try {

 ...

} catch (Exception ex) {
}

Wilayah terlalu sering digunakan

Biasanya, menggunakan terlalu banyak daerah menunjukkan kepada saya bahwa kelas Anda terlalu besar. Ini adalah bendera peringatan yang menandakan bahwa saya harus menyelidiki lebih dalam sedikit kode itu.

Erik van Brakel
sumber
Menangkap pengecualian umum hanya masalah jika Anda mengolahnya kembali tanpa melakukan apa pun. Sebenarnya untuk sebagian besar hal, satu kelas pengecualian sudah cukup. Saya cenderung menggunakan runtime_error.
CashCow
+1 untuk contoh 'tangkap dan buang pengecualian'. Jika Anda tidak melakukan apa pun dengan pengecualian, jangan tangkap. Paling tidak, catat. Pada bagian paling, paling tidak, berikan komentar yang menjelaskan mengapa tidak apa-apa untuk menangkap semua pengecualian dan melanjutkan pada saat itu dalam kode.
EZ Hart
5

Konvensi penamaan kelas yang menunjukkan pemahaman yang buruk tentang abstraksi yang mereka coba ciptakan. Atau itu sama sekali tidak mendefinisikan abstraksi.

Sebuah contoh ekstrem muncul di benak saya di kelas VB yang pernah saya lihat yang diberi judul Datadan panjangnya 30.000+ ... di file pertama . Itu adalah sebagian kelas yang dibagi menjadi setidaknya setengah lusin file lainnya. Sebagian besar metode adalah pembungkus di sekitar procs yang disimpan dengan nama seperti FindXByYWithZ().

Bahkan dengan contoh-contoh yang kurang dramatis, saya yakin kita semua baru saja 'membuang' logika ke kelas yang kurang dipahami, memberinya gelar yang sepenuhnya generik, dan kemudian menyesalinya.

Bryan M.
sumber
5

Fungsi yang menerapkan kembali fungsionalitas dasar bahasa. Misalnya, jika Anda pernah melihat metode "getStringLength ()" dalam JavaScript alih-alih panggilan ke properti ".length" dari string, Anda tahu Anda dalam masalah.

Semut
sumber
5
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...

Tentu saja tanpa jenis dokumentasi dan bersarang sesekali #defines

Sven
sumber
Saya telah melihat persis "pola" ini kemarin ... dalam kode produksi ... dan lebih buruk lagi ... dalam kode produksi C ++: - /
Oliver Weiler