Kode mewah pendek yang dikomentari vs. kode mudah dimengerti yang tidak diomongkan lebih lama - mana yang lebih disukai?

18

Terkadang suatu algoritma dapat ditulis dalam dua cara:

  • Cara pendek dan mewah; atau
  • Cara yang lebih panjang dan mudah dipahami.

Misalnya, ini cara yang lebih panjang dan lebih mudah untuk menyalin string sourceke destdalam C:

*dest = *source;
while (*source != '\0') {
    source++;
    dest++;
    *dest = *source;
} (true);

Dan ini cara yang pendek dan mewah.

// Copy string source to dest
while (*dest++ = *source++);

Saya selalu mendengar dan membaca bahwa kode mewah harus dihindari, dan saya cenderung setuju. Tetapi bagaimana jika kita mempertimbangkannya? Anggaplah, seperti dalam contoh di atas, kita memiliki kode yang tidak diomentari, lebih panjang dan lebih mudah dipahami, dan kode mewah yang dikomentari dengan baik? Apakah kode yang tidak mewah masih disukai?

EDIT: Banyak yang mengomentari nama variabel, jadi saya telah memodifikasi kode contoh agar tidak menjadikannya faktor ketika lebih memilih yang lain. Saya mencoba untuk menghapus penugasan ganda pada contoh pertama, tetapi itu hanya membuat kode kurang dibaca.

Mungkin ini bukan contoh terbaik karena banyak yang menemukan kode 'mewah' lebih mudah dibaca dan dimengerti daripada kode yang lebih panjang. Idenya adalah memiliki satu kode yang lebih panjang yang jauh lebih mudah dipahami daripada kode yang sangat pendek namun rumit.

EDIT2: Ini contoh baru yang saya dapat dari SO :

Versi mewah berkomentar:

//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );

Versi panjang tanpa komentar:

int Sum = 0;
for (int i = 1; i < N; ++i)
{
   Sum ^= i; //or Sum = Sum ^ i;
}
Gablin
sumber
2
@ gablin: "baik" adalah sebuah kata, tetapi kata sifat dengan arti yang agak berbeda dari "baik," dan tidak digunakan secara luas lagi (setidaknya di AS) Bentuk kata keterangan "baik" adalah "baik," seperti pada "kode yang dikomentari dengan baik."
John M Gant
@ John: Ah ya, tentu saja. Saya telah memperbarui pertanyaannya. Terima kasih.
gablin
2
Dengan cara apa jalan pendek 'mewah'? Itu adalah bagian buku teks dari kode C bahwa siapa pun yang mengaku tahu C harus dapat membaca tanpa masalah. Terseness bukan berarti 'mewah'.
JBRWilkinson
@ JBRWilkinson: Seperti yang saya katakan di bagian modifikasi dari pertanyaan, contoh ini tidak bagus karena versi "mewah" tampaknya tidak semewah itu. Tujuannya adalah untuk memiliki satu cara pendek tetapi tidak dapat dipahami dengan komentar dan kemudian cara yang lebih panjang tetapi jauh lebih mudah dibaca tanpa komentar.
gablin
@ gablin: Hasil edit Anda mengganggu jawaban saat ini.
Maniero

Jawaban:

28

Saya biasanya lebih suka mengekstrak kode mewah ke metode sendiri ..

Alih-alih mengomentari kode mewah, nama metode haruslah yang dibutuhkan untuk memperjelas.

char *copy_string(char *s, const char *t) {    
    while (*s++ = *t++); 
    return s;
}
Mongus Pong
sumber
3
Poin yang bagus. Memperhitungkan kode mandiri jauh lebih baik daripada komentar. Compiler tahu bagaimana cara inline jika diperlukan.
dbkk
Ah ya, itu cara yang bagus untuk membuat komentar menjadi usang. Tetapi meskipun demikian, apakah Anda selalu lebih suka kode mewah daripada kode yang lebih panjang?
Gablin
Secara umum, ya. Saya merasa metode yang singkat dan bernama baik membuat kode lebih mudah dibaca dan dipelihara. Kompleksitas yang dimasukkan ke dalam metodenya sendiri menjadikan penggunaan kembali lebih mudah dan jelas. Selalu ada pengecualian, pada akhirnya selalu tergantung pada kode.
Mongus Pong
Tentunya fungsi Anda harus dinamai 'strcpy'?
JBRWilkinson
Ada kesalahan dalam potongan kode itu. Apa yang dikembalikan? Apa yang seharusnya dikembalikan? Jadikan itu sebagai metode yang tidak berlaku dan dilakukan;)
Christian Mann
10

Saya semua untuk versi yang lebih panjang. Masalah dengan versi pendek kode, selain lebih sulit dibaca oleh beberapa programmer, adalah bahwa sebagian besar waktu lebih sulit untuk menemukan kesalahan hanya dengan melihatnya.

Saya punya contoh kehidupan nyata. Dalam produk kami, kami memiliki cuplikan kode berikut:

if (++someCounter < MAX_VALUE) {
    // Do something that has to be done only MAX_VALUE times
}

Kode ini terlihat sangat masuk akal pada pandangan pertama, tetapi setelah jangka waktu yang lama, penghitung ini meluap dan merusak kondisi (dalam skenario kehidupan nyata kami menghancurkan sistem produksi klien kami dengan OOM). Kode ini sedikit kurang "canggih", tetapi jelas bahwa ia melakukan apa yang seharusnya dilakukan:

if (someCounter < MAX_VALUE) {
    ++someCounter;
    // Do whatever it is we came here for
}

Dan Anda dapat mengatakan bahwa pengembang yang menulis kode ini tidak cukup baik (yang tidak benar, ia adalah orang yang cukup cerdas), tetapi saya berpikir bahwa jika teknik pengkodean Anda mengharuskan Anda menjadi super-duper, ahli pemrograman, D Untuk mendapatkan kode Anda yang benar, Anda melakukan sesuatu yang salah. Kode Anda harus sesederhana mungkin demi Anda dan bagi siapa pun yang harus mempertahankan kode ini setelah Anda (yang mungkin tidak sepintar Anda).

Jadi - saya semua untuk kesederhanaan dan kejelasan.

Sunting: Oh, dan mengenai komentar - tidak masalah. Banyak orang yang tidak akan membaca komentar ( http://www.javaspecialists.co.za/archive/Issue039.html ) dan mereka yang tidak akan memahami kode Anda tanpa komentar, tidak akan memahaminya dengan cukup baik sehingga mereka tidak dapat mempertahankannya. Tujuannya adalah untuk membantu orang melihat bahwa kode tertentu "benar", komentar tidak dapat membantu dengan itu.

Hila
sumber
1
"menghancurkan sistem produksi klien kami" - itu sangat buruk: -S
"Masalah dengan versi pendek kode, selain dari itu menjadi lebih sulit bagi beberapa programmer untuk membaca" - setiap bagian dari kode bisa sulit "untuk beberapa programmer" untuk dibaca. Anda hanya perlu menemukan programmer yang cukup bodoh. Jangan membodohi kode ke penyebut terendah.
quant_dev
@quant_dev: sebaliknya, "Debugging dua kali lebih keras daripada menulis kode di tempat pertama. Karena itu, jika Anda menulis kode sepintar mungkin, Anda, menurut definisi, tidak cukup pintar untuk men-debug itu." - Brian W. Kernighan
Michael Borgwardt
@MichaelBorgwardt Saya tidak akan menerapkan diktum Kernighan secara membuta pada setiap situasi yang mungkin terjadi. Contoh OP adalah fungsi yang ditulis "sepintar mungkin" (atau sedekat mungkin) dan harusnya cukup mudah untuk di-debug, jika diperlukan debugging. Di sisi lain, oneliners bit-twiddling yang rumit bisa sangat pintar, tetapi tentu saja akan lebih sulit untuk di-debug. (Juga: Kernighan mengasumsikan bahwa keterampilan pengkodean = keterampilan debugging. Tidak harus demikian. Saya telah berhasil mendebug kode yang tidak akan bisa saya tulis.)
quant_dev
6

Saya biasanya lebih suka versi yang lebih panjang. Dua alasan utama muncul dalam pikiran:

  • Semakin banyak orang cenderung memahaminya dengan sedikit usaha (dengan asumsi itu bukan contoh "standar" seperti salinan string ini).
  • Dimungkinkan untuk menempatkan breakpoint pada pernyataan individual dan melangkah maju dengan debugger.

Untuk yang terbaik dari kedua dunia, bungkus kode dalam suatu fungsi, yang namanya mengomentari untuk Anda:

void copy_string(char *s, char *t)
{
    *s = *t;
    while (*t != '\0') {
        t++;
        s++;
        *s = *t;
    }
}

Satu-satunya alasan untuk tidak melakukan ini adalah jika kinerja merupakan masalah dan pembuatan profil benar-benar menunjukkan fungsi overhead menjadi signifikan.

Paul Stephenson
sumber
1
Bukankah itu untuk apa inline?
Antsan
Memang, meskipun inlining datang dengan masalah sendiri, seperti harus mengekspos fungsi tubuh dalam file header. Bukankah kompiler modern membuat inline untuk Anda secara otomatis di tempat yang masuk akal?
Paul Stephenson
4

Apa pun yang paling jelas. Seringkali itu adalah cuplikan kode yang mudah dimengerti dan tidak memerlukan komentar ... seperti contoh kedua Anda.

Cuplikan kode yang lebih pendek umumnya lebih mudah dipahami karena jumlah pembaca kurang untuk diingat. Jelas, ada batasan ketika kode terlalu dikaburkan dan saya tidak bermaksud bahwa kejelasan meningkatkan ruang putih harus dipangkas.

Komentar tidak boleh menyatakan apa pun yang jelas dari kode, yang hanya membuat pembaca membaca hal yang sama dua kali. Bagi saya cuplikan pertama memerlukan klarifikasi. Mengapa pengembang belum menggunakan do...whileloop untuk menghapus duplikat *s = *t;tugas? Saya harus mengurai lebih banyak kode untuk menyadari bahwa itu menerapkan salinan string. Suatu komentar akan lebih membantu pada kode yang lebih panjang ini daripada pada kode yang lebih pendek.

Komentar pada snippet kedua hampir redundan seperti itu sementara loop praktis idiomatis, tetapi ia mengatakan apa yang dilakukan kode pada level yang lebih tinggi daripada kode itu sendiri yang membuatnya menjadi komentar yang berguna.

CB Bailey
sumber
Pengembang (saya) tidak menggunakan do ... whilehanya karena saya tidak memikirkannya ketika saya menulis pertanyaan. Terima kasih telah menunjukkannya. ^^ Cuplikan kedua mungkin jelas bagi Anda, tetapi jelas bukan untuk saya.
gablin
4

Masalahnya adalah bahwa tidak ada definisi yang jelas short fancy codekarena sangat tergantung pada level programmer. Sementara beberapa orang tidak memiliki masalah dalam memahami suatu while(*s++ = *t++);ekspresi, yang lain akan.

Secara pribadi saya menemukan yang while(*s++ = *t++);terbaca sempurna dan yang lebih lama lebih sulit dibaca. Orang lain mungkin tidak setuju.

Apapun, itu hanya masalah menggunakan akal sehat. Keterbacaan harus jelas menjadi prioritas, tetapi ada titik di mana kode yang lebih panjang menjadi kurang terbaca ketika semakin lama. Verbositas sering mengurangi keterbacaan dari pengalaman saya.

Wolph
sumber
Itu membuat saya sedih bahwa tema dari banyak jawaban ini adalah "pengembang mungkin tidak mengenali cara standar untuk menulis strcpy () dalam C"
AShelly
Seharusnya tidak - itu tidak berarti bahwa tidak ada programmer yang lebih baik, lebih dari itu a) kita tidak mengajar C lagi dan b) bahwa kekuatan C juga kelemahannya - dalam sementara itu loop adalah dapat dimengerti oleh seseorang yang berlatih di C yang juga sangat misterius dan di dunia yang berusaha untuk menulis kode aman yang cukup menakutkan untuk apa yang disiratkannya tentang apa yang dapat Anda lakukan dalam C
Murph
Jadi kami menemukan diri kami dengan tantangan lain untuk tugas sehari-hari kami. Perlu menebak tingkat pemahaman bahasa umum dari rekan langsung kami sehingga ulasan kode kami akan tetap konstruktif. Tidak terjerumus dalam pertempuran yang merupakan ungkapan niat yang "benar", lebih bersih.
frogstarr78
2

Saya harus tidak setuju dengan sebagian besar jawaban lain di sini - saya pikir (setidaknya dalam hal ini) kode yang lebih pendek lebih baik. Bertentangan dengan klaim Anda, kode yang lebih panjang tidak "lebih mudah", setidaknya untuk pembaca. Jika ada, Anda tampaknya telah keluar dari keinginan Anda untuk membuatnya lebih lama, meskipun itu membuat kode lebih sulit untuk dipahami dan / atau dijamin operasi yang benar.

Secara khusus, memiliki tugas byte pertama dari string luar loop, terpisah dari tugas untuk byte lain, berarti orang harus jauh lebih berhati-hati dalam membaca untuk memastikan bahwa semua byte disalin dengan benar. Urutan dasar tindakan dalam versi yang lebih pendek jauh lebih mudah untuk diverifikasi. Satu-satunya masalah sebenarnya adalah dalam pemformatan - saat Anda memiliki badan loop kosong yang disengaja, yang terbaik adalah membuatnya menjadi jelas, sesuatu seperti:

while (*dest++ = *source++)
    ;

atau bahkan:

while (*dest++ = *source++)
    ; /* no body */

Beberapa orang lebih suka menggunakan kawat gigi sebagai gantinya:

while (*dest++ = *source++)
    {}

Terlepas dari pemformatan yang Anda inginkan, cukup banyak kesalahan yang dilakukan dengan hal-hal seperti:

if (x>y);
     x = z;

... bahwa penting untuk memastikan bahwa 1) sudah jelas apa yang sebenarnya dikontrol oleh aliran-kontrol, dan 2) sudah jelas bahwa kode itu ditulis mengetahui apa yang dikontrol olehnya, jadi seseorang yang membacanya tidak membuang waktu untuk mencoba untuk mengetahui apakah mereka baru saja menemukan bug.

Jerry Coffin
sumber
Ya, kalau dipikir-pikir contoh khusus ini, versi 'mewah' mungkin lebih mudah dibaca daripada versi yang lebih panjang. Jika saya bisa memikirkan contoh yang lebih baik saya akan, tetapi saya tidak dapat saat ini. Tetapi saya tidak "menyimpang dari cara saya" untuk membuatnya lebih lama - itu adalah bagaimana saya akan menulis salinan string, setidaknya pada awalnya. Ini mungkin bukan pendekatan terbaik, tapi itu tidak dibuat lebih lama dari yang dibutuhkan dengan niat.
gablin
2
Keep it simple, stupid!

Pastikan programmer lain dapat memahami apa yang kode Anda lakukan — dan bahkan lebih baik jika dilihat sekilas (di sinilah nama dan komentar yang baik muncul dengan sendirinya).

Kay-fu bit-twiddling dan perakitan inline bagus untuk optimasi (mungkin tidak perlu dan prematur), tetapi ketika Anda bahkan tidak dapat memahami kode yang Anda tulis ketika menemukan bug di dalamnya dua bulan kemudian .. Apa gunanya? Anda akan menghabiskan waktu dan usaha sendiri.

Saya sering merujuk ke Zen Python dalam situasi ini. Khususnya:

Explicit is better than implicit.
Simple is better than complex.
Humphrey Bogart
sumber
1

Jangan menulis kode mewah dalam perangkat lunak produksi. Saya tahu rasanya senang bisa benar-benar menulis itu, dan lebih pendek. Menulis kode mewah secara signifikan meningkatkan nilai "WTF / menit", dengan kata lain menurunkan kualitas.

teks alternatif

Tamás Szelei
sumber
1

Itu tentu saja sepenuhnya tergantung pada keadaan. tetapi secara umum, saya menemukan ini sebagai aturan praktis yang baik:

Debugging dua kali lebih sulit daripada menulis kode di tempat pertama. Oleh karena itu, jika Anda menulis kode sepintar mungkin, Anda, menurut definisi, tidak cukup pintar untuk debug itu.

~ Brian Kernighan

violet313
sumber
lebih panjang tapi lebih bermakna, bahkan elegan , daripada akronim CIUMAN yang lebih kompak ~ harap ironi di sana tidak hilang; p
violet313
0

Dalam pengalaman saya, kemenangan terbesar dalam hal kode mewah pendek cenderung menggunakan rekursi daripada iterasi. Ini juga salah satu hal yang paling sulit untuk dipahami dalam sekilas kode, kecuali jika Anda bekerja dalam jenis bahasa di mana semuanya bersifat rekursif. Saya masih menginginkannya untuk keanggunan dan kecepatan pengembangan yang ditawarkannya, tetapi saya mencoba memastikan bahwa komentarnya terperinci jika kelihatannya akan buram bagi para pengelola di masa depan atau diri saya di masa depan.

glenatron
sumber
0

Saya mulai tidak percaya pada komentar. Terlalu sering, komentar tidak diperbarui ketika kode diperbarui dan jauh dari ketinggalan zaman atau mewakili aturan dari klien / manajemen yang tidak lagi relevan.

Sudah sampai pada titik dalam beberapa kasus di mana komentar bahkan tidak cocok dengan kode yang mereka gambarkan lagi.

Jika saya harus memilih antara pendek / mewah dan lebih lama / lebih mudah dimengerti maka saya selalu memilih yang terakhir kecuali ada alasan yang sangat bagus.

Steven Evers
sumber
0

Keterbacaan dan pemeliharaan adalah kunci, dan contoh kedua Anda (yaitu yang lebih lama) jauh lebih baik dari keduanya. Tetapi mengapa membatasi diri Anda pada dua pilihan? Bahkan kode yang lebih panjang terlalu kompleks (IMHO) untuk tidak memberi tahu lebih lanjut. Saya akan memasukkannya ke dalam metode sendiri dengan Javadoc yang sesuai (atau apa pun) dan nama metode yang sesuai.

Chris Knight
sumber