Karmaşık kodu açıklayan yorumların nesi yanlış?


236

Pek çok insan "yorumlar 'nedenini açıklamalı, ama' nasıl 'değil" iddiasında. Diğerleri "kodun kendi kendini belgelemesi gerektiğini" ve yorumların kıt olması gerektiğini söylüyor. Robert C. Martin, (kendi sözlerime göre yeniden ifade edilmiştir) sık sık "yorumların kötü yazılmış kod için özür dilediğini" iddia ediyor.

Sorum şu:

Tanımlayıcı bir yorumla karmaşık bir algoritmayı veya uzun ve karmaşık bir kod parçasını açıklamanın nesi yanlış?

Bu yolla, diğer geliştiriciler (kendiniz de dahil olmak üzere), ne yaptığını anlamak için tüm algoritma satırını okumak zorunda kalmak yerine, sadece basit İngilizce dilinde yazdığınız kolay açıklayıcı yorumları okuyabilirler.

İngilizce insanlar tarafından kolayca anlaşılmak üzere 'tasarlanmıştır. Ancak Java, Ruby veya Perl, insan tarafından okunabilirliği ve bilgisayar tarafından okunabilirliği dengelemek için tasarlanmıştır, böylece metnin insan tarafından okunabilirliğini tehlikeye atar. Bir insan bir İngiliz parçasını aynı anlama sahip bir kod parçasını anlayabildiğinden çok daha hızlı anlayabilir (işlem önemsiz olmadığı sürece).

Öyleyse, kısmen okunabilir bir programlama dilinde yazılmış karmaşık bir kod parçasını yazdıktan sonra, neden kodun dostça ve anlaşılır İngilizce olarak işlendiğini açıklayan açıklayıcı ve özlü bir yorum eklemiyorsunuz?

Bazıları "kodun anlaşılması zor olmamalı", "işlevleri küçük yap", "açıklayıcı isimler kullan", "spagetti kodunu yazma" diyecek.

Ama hepimiz biliyoruz ki bu yeterli değil. Bunlar sadece kurallardır - önemli ve faydalı olanlar - ancak bazı algoritmaların karmaşık olduğu gerçeğini değiştirmezler. Ve bu yüzden satır satır okurken anlamak zordur.

Genel bir işlem hakkında birkaç satır yorum içeren karmaşık bir algoritmayı açıklamak gerçekten o kadar mı kötü? Bir yorum ile karmaşık kodu açıklamanın nesi yanlış?


14
Kıvrımlıysa, daha küçük parçalara yeniden yerleştirmeyi deneyin.
Vaughan Hileleri

151
Teoride teori ile pratik arasında bir fark yoktur. Uygulamada var.
Scott Leadley

5
@mattnz: daha doğrudan, yorumu yazdığınızda, bu kodun çözdüğü problemin üstesinden gelinir. Bir dahaki sefere ziyaret ettiğinizde, bu sorunla ilgili daha az yeteneğiniz olacak .
Steve Jessop

26
İşlev veya yöntemin "ne" yaptığı, adından açıkça anlaşılmalıdır. Nasıl yapar onun kodundan açıktır. Neden bu şekilde yapılır, hangi örtülü varsayımların kullanıldığı, algoritmanın anlaşılması için hangi makalelerin okunması gerektiği vs. yorumlarda bulunmalıdır.
SK-mantık

11
Aşağıdaki yanıtların birçoğunun sorunuzu amaçlı olarak yanlış yorumladığını hissediyorum. Kodunuzu yorumlamakta yanlış bir şey yok. Açıklayıcı bir yorum yazmanız gerektiğini düşünüyorsanız, o zaman yapmanız gerekir.
Tony Ennis

Yanıtlar:


408

Layman'ın terimiyle:

  • Orada yorumlarla yanlış bir şey se başına. Yanlış olan, bu tür yorumlara ihtiyaç duyan kod yazmak ya da basit İngilizce dilinde açıklandığı sürece, karmaşık kod yazmanın uygun olduğunu varsaymaktır.
  • Kodu değiştirdiğinizde yorumlar otomatik olarak güncellenmez. Bu nedenle çoğu zaman yorumlar kodla eşzamanlı değildir.
  • Yorumlar kodu test etmeyi kolaylaştırmaz.
  • Özür dilemek fena değil. Özür dilemeni gerektiren (yaptığını kolayca anlaşılamayan bir kod yazmak) yapmak kötü.
  • Karmaşık bir sorunu çözmek için basit kod yazabilen bir programcı, karmaşık kod yazandan daha iyidir ve daha sonra kodunun ne yaptığını açıklayan uzun bir yorum yazar.

Alt çizgi:

Kendinizi açıklamak iyidir, bunu yapmak zorunda kalmamak daha iyidir.


91
İyi bir yorum işini çok daha kısa sürede yapabileceği zaman, harcama yapan işverenin para yeniden yazma kodunu daha fazla açıklayıcı olması için haklı kılmak imkansızdır. İyi bir programcının kararını her seferinde kullanması gerekir.
aecolley

34
@aecolley Başlamak için kendi kendini açıklayıcı kod yazmak daha iyidir.
Tulains Córdova

127
Bazen kendi kendini açıklayan kod, günümüzdeki HW&SW ile ilgili bir sorunu çözecek kadar verimli olmayabilir. Ve iş mantığı çok ünlüdür ... bükülüyor. Zarif yazılım çözümlerine sahip olan sorunların alt kümesi, çözmek için ekonomik olarak yararlı olan sorun kümesinden önemli ölçüde daha küçüktür.
Scott Leadley

62
@ rwong: tersine sık sık kendimi iş mantığına daha fazla yorum yazarken buluyorum, çünkü kodun belirtilen şartlara tam olarak nasıl uyduğunu göstermemiz önemlidir: "Bu, ne olursa olsun, Bölüm altında kablo sahtekarlığı için hapse girmemizi önleyen çizgidir. ceza kanunu ". Bu sadece bir algoritma ise, bir programcı, kesinlikle gerekli ise sıfırdan amacını çözebilir. İş mantığı için aynı anda aynı odada bulunan bir avukata ve müşteriye ihtiyacınız var. Muhtemelen benim "sağduyum" ortalama uygulama programcısının farklı bir etki alanındadır ;-)
Steve Jessop

29
@ user61852 Sadece bu kodu yazan ve içine harcanan son $ dönemini harcayan, sizin için açıklayıcı olanın dışında, bundan beş yıl sonra bile, tüm bunları saklamanız veya düzenlemeniz gereken, sizin için açıklayıcı olmayabilir. O size bakmak zorunda değilsiniz ki olası insanlar. "Kendinden açıklamalı" tanımların berbat bir kutsal kasesidir.
Shadur

110

Kodun karmaşık veya kafa karıştırıcı olmasının birçok farklı nedeni var. En yaygın nedenleri iyi değil her türlü yorum ekleyerek, daha az kafa karıştırıcı hale getirmek için kod üstlenmeden tarafından ele alınmaktadır.

Ancak, iyi seçilmiş bir yorumun en iyi seçenek olduğu durumlar vardır.

  • Karmaşık ve kafa karıştırıcı olan algoritmanın kendisi ise sadece uygulaması değil - matematik dergilerinde yazılan ve sonradan Mbogo'nun Algoritması olarak anılan türden biriyse, uygulamanın en başında bir yorum yazdınız. "Bu, orijinal olarak burada tarif edilen widget'ları yeniden düzenlemek için Mbogo'nun Algoritmasıdır: [kağıdın URL'si]. Bu uygulama, Alice ve Carol'ın [başka bir kağıdın URL'si] iyileştirmelerini içerir." Bundan daha fazla ayrıntıya girmeye çalışmayın; Birisi daha fazla ayrıntıya ihtiyaç duyuyorsa, muhtemelen makalenin tamamını okumalıdır.

  • Bazı özel gösterimlerde bir veya iki satır olarak yazılabilecek ve büyük bir zorunluluk koduna dönüştürülmüş bir şey aldıysanız, bu bir veya iki satırlık özel gösterimi fonksiyonun üzerindeki bir açıklamaya koymanız iyi bir yoldur. okuyucuya ne yapması gerektiğini söyle . Bu, "ancak yorum kodla senkronize edilmezse" argümanına bir istisnadır, çünkü özel gösterim, kodda bulunan hataları bulmaktan daha kolaydır. (Bunun yerine İngilizce bir açıklama yazarsanız, bunun tersi de geçerlidir.) İyi bir örnek burada: https://dxr.mozilla.org/mozilla-central/source/layout/style/nsCSSScanner.cpp#1057 ...

    /**
     * Scan a unicode-range token.  These match the regular expression
     *
     *     u\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?
     *
     * However, some such tokens are "invalid".  There are three valid forms:
     *
     *     u+[0-9a-f]{x}              1 <= x <= 6
     *     u+[0-9a-f]{x}\?{y}         1 <= x+y <= 6
     *     u+[0-9a-f]{x}-[0-9a-f]{y}  1 <= x <= 6, 1 <= y <= 6
    
  • Kod genel olarak basitse, ancak aşırı kıvrılmış, gereksiz ya da sadece yanlış görünen bir ya da iki şey içeriyorsa , ancak nedenlerden dolayı bu şekilde olması gerekiyorsa, şüpheli görünen bitin hemen üstüne bir yorum yazın; nedenlerini siz belirtirsiniz . İşte basit bir örnek, açıklanması gereken tek şey bir sabitin neden belirli bir değere sahip olduğu.

    /* s1*s2 <= SIZE_MAX if s1 < K and s2 < K, where K = sqrt(SIZE_MAX+1) */
    const size_t MUL_NO_OVERFLOW = ((size_t)1) << (sizeof(size_t) * 4);
    if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
        nmemb > 0 && SIZE_MAX / nmemb < size)
      abort();
    

25
Bu bir öfke 4olmalı CHAR_BIT / 2;-)
Steve Jessop

@SteveJessop: Herhangi bir şey CHAR_BITS16 ve sizeof (size_t) 2 olan bir uygulamayı engeller mi ?
supercat

2
@supercat Açıkçası C99, hangi örnek demektir engellemektedir şey görmüyorum olduğunu teknik olarak yanlış. O (biraz değiştirilmiş versiyonu) OpenBSD en alınacaktır olur reallocarrayve OpenBSD genellikle de olmaz olasılıklara catering inanmıyor onların ABI.
zwol

3
@Zack: Kod POSIX varsayımlar etrafında tasarlanmış ise, CHAR_BITS kullanarak kod 8. dışındaki değerlerle işe yarayabilir izlenimini verebilir
SuperCat

2
@Zack: Kesin genişlikte işaretsiz türlerin kullanışlı olması için, anlambilimlerinin boyutundan bağımsız olarak tanımlanması gerekir int. Olduğu gibi, uint32_t x,y,z;anlamı (x-y) > z, büyüklüğüne bağlıdır int. Ayrıca, sağlam kod yazmak için tasarlanan bir dil, programcıların hesaplamaların tür aralığını aşması beklenen bir tür arasında ayrım yapmasına izin vermeli ve tür aralığını aşan hesapların tutulduğu yere göre hesaplamaları nerede tuttuğunu; türün aralığını aşması beklenmez, ancak ...
supercat

61

Peki karmaşık kodun bir yorum ile açıklanmasında yanlış olan ne?

Bu bir doğru veya yanlış değil, Wikipedia makalesinde tanımlandığı gibi “en iyi uygulama” meselesidir :

En iyi uygulama, tutarlı bir şekilde diğer yöntemlerle elde edilenlerden daha iyi sonuçlar gösteren ve kıyaslama olarak kullanılan bir yöntem veya tekniktir.

Bu yüzden en iyi uygulama, önce kodu geliştirmeye çalışmak ve eğer mümkün değilse İngilizce'yi kullanmaktır.

Bu bir yasa değil, ancak yeniden yapılanma gerektiren yeniden kodlanmış kod bulmaktan daha sık rastlanan, yorum gerektiren koddan daha sık rastlanan durumdur, en iyi uygulama bunu yansıtır.


42
+1 için "yorum gerektiren yeniden kodlanmış koddan daha fazla yeniden düzenleme gerektiren kod bulmak çok daha yaygın"
Brandon

7
Tamam, ama bu yorum ne sıklıkta: //This code seriously needs a refactor
Erik Reppen

2
Tabii ki, sıkı bir bilimsel çalışma ile desteklenmeyen en iyi uygulama denilen herhangi bir şey sadece bir fikirdir.
Blrfl

54

Güzel, mükemmel hazırlanmış, iyi yapılandırılmış ve okunabilir kodunuzun işe yaramadığı bir gün gelecek. Yoksa yeterince iyi çalışmayacak. Veya çalışmadığı ve ayarlanması gereken özel bir durum ortaya çıkacaktır.

Bu noktada, işleri doğru şekilde çalışması için değiştiren bir şey yapmanız gerekecektir. Özellikle performans sorunlarının olduğu durumlarda, ancak sıklıkla birlikte çalıştığınız kitaplıklardan, API'lerden, web hizmetlerinden, mücevherlerden veya işletim sistemlerinden birinin beklendiği gibi davranmadığı senaryolarda, mutlaka inelegant, ancak karşı sezgisel veya açık değil.

Bu yaklaşımı neden seçtiğinizi açıklamak için bazı yorumlarınız yoksa, gelecekte birinin (ve hatta sizin bile sizin olabileceğiniz) bir koda bakması konusunda çok iyi bir şans var. daha okunaklı ve zarif bir şey ve yanlışlıkla düzeltmenizi geri alın, çünkü düzeltme gibi görünmüyor.

Herkes her zaman mükemmel bir kod yazsa, kusurlu görünen kodun gerçek dünyadan zor bir müdahale üzerinde çalıştığı açıktır, ancak işler böyle olmaz. Çoğu programcı kafa karıştırıcı veya biraz karışık kod yazmaktadır, bu nedenle karşılaştığımızda bunu düzeltmek doğal bir eğilimdir. Yemin ederim, kendimi yazdığım eski kodları okuduğumda kendimi gerçek bir salak .

Bu yüzden yorumları kötü kod için bir özür olarak düşünmüyorum, ama bariz şeyi neden yapmadığına dair bir açıklama olarak düşünüyorum. Having // The standard approach doesn't work against the 64 bit version of the Frobosticate Libraryo kütüphaneye karşı kodu ve testin bu bölümünde dikkat gelecekteki kendini dahil olmak üzere geleceğe geliştiriciler, izin verecektir. Tabii ki, yorumlarınızı kaynak kontrolünüze de ekleyebilirsiniz, ancak insanlar yalnızca bir şeyler ters gittiğinde bunlara bakarlar. Kodu değiştirdikçe kod yorumlarını okuyacaklar.

Bize her zaman teorik olarak mükemmel kod yazmamız gerektiğini söyleyen insanlar, gerçek dünya ortamlarında programlama konusunda çok fazla tecrübeye sahip insanlar değildir. Bazen belirli bir seviyede performans gösteren kod yazmanız gerekir, bazen kusurlu sistemler ile birlikte çalışmanız gerekir. Bu, zarif ve iyi yazılmış yöntemlerle yapamayacağınız anlamına gelmez, ancak açık olmayan çözümlerin açıklamaya ihtiyacı var.

Hiç kimsenin okuyamayacağını bildiğim hobi projeleri için kod yazarken, kafamı karıştırmakta olduğum kısımları yine de yorumluyorum - örneğin, herhangi bir 3D geometrisi tamamen evde olmadığım matematik içerir - çünkü ne zaman döneceğimi biliyorum altı ay içinde bu işlerin nasıl yapıldığını tamamen unutmuş olacağım. Bu kötü kod için bir özür değil, kişisel bir kısıtlamanın bir göstergesi. Bunu açık bırakmadan yapacağım tek şey gelecekte kendim için daha fazla iş yaratmak. Gelecekteki kendimin, şimdi kaçınabilmem için gereksiz yere bir şeyler öğrenmesini istemiyorum. Olası değeri ne olurdu?


5
@ Hıristiyan mı? İlk satır, bu ifadeye atıfta bulunur, kesinlikle, ama ötesinde, anladığım kadarıyla biraz daha geniş.
glenatron 13

9
"Yemin ederim, kendimi yazdığım eski kodları okuduğumda kendim için gerçek bir salak." Dört yıldır gelişim kariyerime giriyorum ve bunun 6 aydan daha eski herhangi bir şeye baktığımda meydana gelen bir olay olduğunu görüyorum.
Ken

6
Çoğu durumda, en bilgilendirici ve faydalı tarihsel bilgiler, dikkate alınan ancak karar verilen şeyler ile ilgilidir. Birinin X'e yaklaşımını seçtiği ve Y'nin daha iyi görüneceği başka bir yaklaşımın ortaya çıktığı birçok durum vardır; Bazı durumlarda, Y "neredeyse" X'ten daha iyi çalışacaktır, ancak aşılmaz sorunları olduğu ortaya çıkmıştır. Bu sorunlar nedeniyle Y'den kaçınılması halinde, bu tür bilgiler başkalarının Y yaklaşımını uygulamadaki başarısız girişimlerle zamanlarını boşa harcamalarını önlemeye yardımcı olabilir
supercat

4
Günden güne kullandığım eseri çok fazla yorum yapıyorum - uzun vadede orada bulunmuyorlar, ancak daha sonra ne yapacağımı hatırlatmak için TODO notuna ya da kısa bir bölüme bırakmak yararlı olabilir sabahları hatırlatma.
glenatron

1
@Lilienthal, son paramın kişisel projelerle sınırlı olduğunu sanmıyorum - dedi ki, "... hala kafa karıştırıcı bulduğum kısımları yorumluyorum " dedi .
Wildcard

29

Yorumlara duyulan ihtiyaç, kodun soyutlama seviyesiyle ters orantılıdır.

Örneğin, Assembly Dili, en pratik amaçlarla, yorum yapılmadan anlaşılmazdır. İşte Fibonacci serisinin terimlerini hesaplayan ve basan küçük bir programdan bir alıntı :

main:   
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
    mov ax,'00'                     ; initialize to all ASCII zeroes
    mov di,counter                  ; including the counter
    mov cx,digits+cntDigits/2       ; two bytes at a time
    cld                             ; initialize from low to high memory
    rep stosw                       ; write the data
    inc ax                          ; make sure ASCII zero is in al
    mov [num1 + digits - 1],al      ; last digit is one
    mov [num2 + digits - 1],al      ; 
    mov [counter + cntDigits - 1],al

    jmp .bottom         ; done with initialization, so begin

.top
    ; add num1 to num2
    mov di,num1+digits-1
    mov si,num2+digits-1
    mov cx,digits       ; 
    call    AddNumbers  ; num2 += num1
    mov bp,num2         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jz  .done           ;

    ; add num2 to num1
    mov di,num2+digits-1
    mov si,num1+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num1 += num2
.bottom
    mov bp,num1         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jnz .top            ;
.done
    call    CRLF        ; finish off with CRLF
    mov ax,4c00h        ; terminate
    int 21h             ;

Yorumlar olsa bile, grok için oldukça karmaşık olabilir.

Modern Örnek: Regex'ler genellikle çok düşük soyutlama yapılarıdır (küçük harfler, sayı 0, 1, 2, yeni satırlar, vb.). Muhtemelen örnekler şeklinde yorumlara ihtiyaçları vardır (Bob Martin, IIRC, bunu kabul eder). İşte (bence) HTTP (S) ve FTP URL'leri ile eşleşmesi gereken bir regex:

^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\\+&amp;%\$#\=~_\-]+))*$

Diller soyutlama hiyerarşisini geliştirdikçe, programcı yerleşik belgeler sağlamak için uyarıcı soyutlamalar (değişken adı, işlev adları, sınıf adları, modül adları, arayüzler, geri aramalar vb.) Kullanabilir. Bundan faydalanmayı ihmal etmek ve kağıt üzerindeki yorumları kullanmak tembeldir, bakıcıya saygısızlık ve saygısızlıktır.

Ben düşünüyorum C Sayısal Tarifler çoğunlukla aynen tercüme C ++ Sayısal Tarifler olarak başladı ben anlaması, Sayısal Tarifler tüm değişkenler, (fortan cinsinden) a, aa, b, c, ccher sürümü ile bakımı vb. Algoritmalar doğru olabilir, ancak verilen dillerin soyutlamalarından faydalanmadılar. Ve beni sinirlendiriyorlar. Dobbs makalesinden bir örnek - Hızlı Fourier Dönüşümü :

void four1(double* data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    // reverse-binary reindexing
    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            swap(data[j-1], data[i-1]);
            swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };

    // here begins the Danielson-Lanczos section
    mmax=2;
    while (n>mmax) {
        istep = mmax<<1;
        theta = -(2*M_PI/mmax);
        wtemp = sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for (m=1; m < mmax; m += 2) {
            for (i=m; i <= n; i += istep) {
                j=i+mmax;
                tempr = wr*data[j-1] - wi*data[j];
                tempi = wr * data[j] + wi*data[j-1];

                data[j-1] = data[i-1] - tempr;
                data[j] = data[i] - tempi;
                data[i-1] += tempr;
                data[i] += tempi;
            }
            wtemp=wr;
            wr += wr*wpr - wi*wpi;
            wi += wi*wpr + wtemp*wpi;
        }
        mmax=istep;
    }
}

Soyutlama ile ilgili özel bir durum olarak, her dilin belirli ortak görevler için (C'deki dinamik bir bağlantılı listeyi silme) deyimleri / kanonik kod parçacıkları vardır ve nasıl göründüklerinden bağımsız olarak belgelendirilmemelidir. Programcılar bu deyimleri öğrenmeli, çünkü gayri resmi dilin bir parçası.

Öyleyse, alıp götürmek: Kaçınılması mümkün olmayan düşük seviyeli yapı taşlarından inşa edilen salak olmayan kodların yorumlanması gerekiyor. Ve bu WAAAAY'ın olduğundan daha az gerekli.


1
Assembly dilinde hiç kimse böyle bir satır yazmamalı dec dword [term] ; decrement loop counter. Öte yandan, assembly dili örneğinizde eksik olan, bir sonraki kod bloğunun ne yaptığını açıklayan her "kod paragrafı" ndan önce yapılan bir yorumdur. Bu durumda, yorum tipik olarak yalancı koddaki tek bir satıra eşdeğer olur; bunun ;clear the screenardından ekranı silmek için gereken 7 satırı takip eder.
Scott Whitlock

1
Evet, montaj örneğindeki bazı gereksiz yorumlar düşünürdüm, ama adil olmak gerekirse, 'İyi' Montaj stilinin oldukça temsilcisi. Bir veya iki satırlık paragraf prologuyla bile, kodu takip etmek gerçekten zor olurdu. ASM örneğini FFT örneğinden daha iyi anladım. C ++ 'ta yüksek lisans okulunda bir FFT programladım ve böyle bir şeye benzemiyordu, ama sonra STL, yineleyiciler, functors gibi birkaç yöntem çağrıları kullanıyorduk. Monolitik fonksiyon kadar hızlı değil, okunması çok daha kolay. NRinC ++ örneğine zıtlık eklemeye çalışacağım.
Kristian H

Bunu mu demek istediniz ^(((ht|f)tps?)\:\/\/)?(www\.)*[a-zA-Z0-9\-\.]+\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\,\;\?\'\\\+&%\$#\=~_\-]+))*$? Sayısal adreslerin farkında olun.
izabera

Neredeyse benim açımdan: çok düşük seviyeli soyutlamalardan oluşturulan bazı şeyleri okumak veya doğrulamak kolay değildir. Yorumlar (ve çok fazla yoldan ayrılmamak için TESTS) yararlı olabilir ve zarar vermeyebilir. Aynı zamanda, mevcut olan yüksek seviyeli soyutlamaları kullanmamak (: alpha:: num: mümkün olduğunda) iyi yorumlarda bile, yüksek seviyeli soyutlamaları kullanmaktan daha zor anlaşılır hale getirir.
Kristian H

3
+1: "The need for comments is inversely proportional to the abstraction level of the code." Hemen hemen her şeyi özetliyor.
Gerrat

21

Kodlarda yorumlarda yanlış olan bir şey olduğuna inanmıyorum. Yorumların bir şekilde kötü olduğu düşüncesi, bazı programcıların çok fazla şey yapmasından kaynaklanıyor. Bu sektörde, özellikle de aşırı görüşlere yönelik çok fazla bant kavgası var. Yorum yapan yol boyunca bir yerlerde kod kötü kodla eşdeğer oldu ve neden olduğundan emin değilim.

Yorumların sorunları var - başvurdukları kodu güncellerken bunları çok güncel tutmanız gerekir; bu da çok nadiren olur. Bir wiki veya başka bir şey, kodunuzla ilgili ayrıntılı belgeler için daha uygun bir kaynaktır. Kodunuz yorum gerektirmeden okunabilir olmalıdır. Sürüm kontrolü veya revizyon notları, yaptığınız kod değişikliklerini tarif ettiğiniz yerde olmalıdır.

Bununla birlikte, yukarıdakilerin hiçbiri yorumların kullanımını geçersiz kılmaz. İdeal bir dünyada yaşamıyoruz, bu yüzden yukarıdakilerden herhangi biri ne olursa olsun başarısız olursa, geri çekilmek için bazı yorumlarim olsun isterim .


18

Sanırım söylediklerine göre biraz fazla okuyorsun. Şikayetinizin iki ayrı kısmı vardır:

(1) karmaşık bir algoritma veya (2) açıklayıcı bir yorumla uzun ve karmaşık bir kod parçasını açıklamanın nesi yanlış?

(1) kaçınılmazdır. Martin'in sana katılmayacağını sanmıyorum. Hızlı ters kare kök gibi bir şey yazıyorsanız , sadece "kötü kayan nokta biti seviyesi hack" olsa bile, bazı yorumlara ihtiyacınız olacak. Bir DFS veya ikili arama gibi basit bir şeyi engellemek için, kodunuzu okuyan kişinin bu algoritma ile ilgili deneyim sahibi olması pek mümkün değildir ve bu yüzden en azından ne olduğuna dair yorumlarda söz edilmesi gerektiğini düşünüyorum.

Ancak çoğu kod (1) değildir. Nadiren, el yapımı muteks uygulamalarından başka bir şey içermeyen bir yazılım yazacak, kütüphane desteğiyle doğrusal cebir işlemlerini ve yalnızca şirketinizin araştırma grubunun bildiği yeni algoritmaları gizleyeceksiniz. Kodların çoğu kütüphane / çerçeve / API çağrıları, IO, boyler ve birim testlerinden oluşur.

Martin'in bahsettiği kod budur. Ve sorunuza, bölümün başındaki Kernighan ve Plaugher'dan alıntılarla cevap veriyor:

Kötü kodu yorumlamayın - yeniden yazın.

Kodunuzda uzun, kıvrımlı bölümler varsa , kodunuzu temiz tutamazsınız . Bu sorunun en iyi çözümü, gelecekteki geliştiricilerin bu konuda karıştırmasına yardımcı olmak için dosyanın en üstüne paragraf uzunluğunda bir yorum yazmaktır; En iyi çözüm, yeniden yazmaktır.

Ve Martin'in dediği tam olarak bu:

Yorumların doğru kullanımı, kendimizi kodda ifade etmememizdeki tazminatı telafi etmektir ... Yorumlar her zaman başarısız olur. Onlara sahip olmalıyız çünkü kendimizi onlarsız nasıl ifade edeceğimizi her zaman çözemeyiz, ancak kullanımı kutlama için bir neden değildir.

Bu senin (2). Martin, uzun, kıvrılmış kodun yorumlara ihtiyacı olduğunu kabul eder - ancak bu kodun suçunu, yazan herkesin "hepimizin yeterli olmadığını bildiği" fikrini değil, onun üzerine yazanların omuzlarına koyar. O savunuyor:

Çok az yorum içeren açık ve etkileyici kod, çok sayıda yorum içeren karışık ve karmaşık kodlardan çok daha iyidir. Yaptığınız karışıklığı açıklayan yorumları yazmaya zaman harcamak yerine, bu karışıklığı temizlemek için harca.


3
Çalıştığım bir geliştirici, hızlı karekök algoritmasını açıklamak için basitçe "kötü kayan nokta biti seviyesi hackleme" yazdı - onlar benim tarafımdan konuşacaktı. Daha yararlı bir yerlere referansta bulundukları sürece mutlu olurum.
Michael Anderson

8
Bir şekilde katılmıyorum - kötü bir şeyin nasıl daha çabuk işe yaradığını açıklayan bir yorum. Tekrar dokunulmaması muhtemel bazı kodlar göz önüne alındığında (sanırım çoğu kod) daha sonra bir yorum çoğu zaman hataya neden olan büyük bir yeniden yapılandırmadan daha iyi bir iş çözümüdir (sıkıntıya bağlı bir hatayı öldüren bir düzeltme hala bir hatadır). Mükemmel bir şekilde anlaşılabilir bir kodun dünyası bizim için mevcut değil.
gbjbaanb

2
@trysis haha, evet, ancak programcıların sorumlu olduğu ve işadamlarının olmadığı bir dünyada, onlar asla sonsuza kadar altınla kaplandığından asla kusursuz bir arayış içinde boşa harcanmamış bir kod temeli ürettiler.
gbjbaanb

4
@PatrickCollins, internette okuduğum hemen hemen her şeyi ilk seferinde doğru yapmakla ilgili. Neredeyse hiç kimse dağınıklığı düzeltmek için yazılar yazmak istemez! Fizikçiler Comp.Scientists ki "... mükemmel bir küre verilen" demek "Bir sıfırdan geliştirme verilen ..."
gbjbaanb

2
En iyi çözüm, sonsuz zaman verilmiş olarak yeniden yazmaktır; ancak başkasının kod temeli, tipik şirket tarihler ve gerçeği göz önüne alındığında; bazen yapılacak en iyi şey yorum yapmak, bir TODO eklemek: Refactor ve bu refactor'ı bir sonraki sürümde elde etmek; ve dün yapılması gereken bu düzeltme şimdi yapıldı. Sadece yeniden yapılanma hakkındaki tüm bu idealist konuşmanın konusu, işyerinde işlerin gerçekte nasıl yürüdüğünü açıklamamaktadır; Bazen, eski kalitesiz kodların düzeltilmesini engelleyecek daha yüksek öncelikler ve yakında yeterli süreler vardır. İşte bu böyle.
hsanders,

8

Tanımlayıcı bir yorumla karmaşık bir algoritmayı veya uzun ve karmaşık bir kod parçasını açıklamanın nesi yanlış?

Böyle bir şey değil. Çalışmanızı belgelemek iyi bir uygulamadır.

Bununla birlikte, burada yanlış bir ikilik var: temiz kod yazmak - belgelenmiş kod yazmak - ikisi muhalif değil.

Odaklanmanız gereken şey, "karmaşık kodun yorumlandığı sürece sorun değil" olduğunu düşünmek yerine, karmaşık kodu basit kod haline getirmektir.

İdeal olarak, kodunuz basit ve belgelenmiş olmalıdır .

Bu yolla, diğer geliştiriciler (kendiniz de dahil olmak üzere), ne yaptığını anlamak için tüm algoritma satırını okumak zorunda kalmak yerine, sadece basit İngilizce dilinde yazdığınız kolay açıklayıcı yorumları okuyabilirler.

Doğru. Bu nedenle, tüm genel API algoritmalarınızın belgelerde açıklanması gerekir.

Öyleyse, kısmen okunabilir bir programlama dilinde yazılmış karmaşık bir kod parçasını yazdıktan sonra, neden kodun dostça ve anlaşılır İngilizce olarak işlendiğini açıklayan açıklayıcı ve özlü bir yorum eklemiyorsunuz?

İdeal olarak, karmaşık bir kod yazdıktan sonra yapmanız gerekenler (ayrıntılı bir liste değil):

  • taslak olarak düşünün (yani yeniden yazmayı planlayın)
  • algoritma giriş noktalarını / arayüzleri / rolleri / etc resmileştirin (arayüzü analiz edin ve optimize edin, soyutlamaları formüle edin, önkoşulları, önkoşulları ve yan etkileri ve döküman hata durumlarını resmileştirin).
  • test yaz
  • temizleme ve refaktör

Bu adımların hiçbiri yapmak için önemsiz değildir (yani her biri birkaç saat sürebilir) ve bunları gerçekleştirmenin karşılığını hemen almazsınız. Bu nedenle, bu adımlar (neredeyse) her zaman (köşeleri kuran geliştiriciler, köşeleri kuran yöneticiler, son tarihler, pazar kısıtlamaları / diğer gerçek dünya koşulları, deneyim eksikliği vb.) Üzerinde taviz verilir.

[...] bazı algoritmalar karmaşıktır. Ve bu yüzden satır satır okurken anlamak zordur.

Bir API'nin ne yaptığını anlamak için uygulamayı okumaya asla güvenmemelisiniz. Bunu yaptığınızda, uygulamaya göre (arayüz yerine) müşteri kodu uyguluyorsunuz ve bu modül kuplajınızın zaten cehenneme gittiği anlamına geliyor , potansiyel olarak yazdığınız her yeni kod satırı ile belgelenmemiş bağımlılıklar ortaya çıkarıyorsunuz ve zaten teknik borç ekliyorum.

Genel bir işlem hakkında birkaç satır yorum içeren karmaşık bir algoritmayı açıklamak gerçekten o kadar mı kötü?

Hayır - bu iyi. Birkaç satırlık bir yorum eklemek yine de yeterli değil.

Bir yorum ile karmaşık kodu açıklamanın nesi yanlış?

Eğer bundan kaçınılabilirse, karmaşık bir kodun olmaması gerektiği gerçeği.

Karmaşık kodlardan kaçınmak için arayüzlerinizi resmileştirin, uygulamaya harcadığınızdan API tasarımına yaklaşık 8 kat daha fazla harcama yapın (Stepanov, uygulama ile karşılaştırıldığında arayüzde en az 10 kat harcamayı önerdi) ve Sadece bir algoritma yazarak değil, bir proje yaratıyorsunuz.

Bir proje API dokümantasyonu, fonksiyonel dokümantasyon, kod / kalite ölçümleri, proje yönetimi vb. İçerir. Bu işlemlerin hiçbiri tek seferlik, hızlı adımlar atmayacak (hepsi zaman alıyor, öngörü ve planlama gerektiriyor ve hepsi düzenli aralıklarla geri gelmenizi ve ayrıntılarla gözden geçirmenizi / tamamlamanızı gerektiriyor).


3
"Bir API'nin ne yaptığını bulmak için uygulamayı okumaktan asla vazgeçmemelisiniz." Bazen bu, kullanmaya karar vermiş olduğunuz bir yukarı akış tarafından size bulaşır. "Aşağıdaki çirkin Heath Robinson kodu var çünkü basitAPI () satıcının iddia ettiğine rağmen bu donanım üzerinde düzgün çalışmıyor" şeklinde yorumlarla dolu, özellikle tatmin edici bir projem vardı.
pjc50

6

Diğer geliştiricilerin (kendiniz de dahil olmak üzere) ne yaptığını anlamak için tüm algoritma satırını satır satır okumak zorunda kalması yerine, sadece ingilizce yazdığınız arkadaşça açıklayıcı yorumları okuyabilirler.

Bunu "yorumların" küçük bir suistimali olarak kabul ediyorum. Programcı tüm algoritmanın yerine bir şey okumak isterse , fonksiyon belgelerinin bunun için kullanılması gerekir. Tamam, bu nedenle işlev dokümantasyonu kaynaktaki yorumlarda görünebilir (belki de doktor araçları tarafından çıkarılması için), ancak sözdizimsel olarak derleyiciniz söz konusu olduğunda bu bir yorum olsa da, bunları ayrı amaçlarla ayrı düşünmelisiniz. "Yorumlar kıt olmalı" mutlaka "dokümantasyon kıt olmalı", hatta "telif hakkı bildirimleri az olmalı" anlamına gelmez!

İşlevdeki yorumlar , kodun yanı sıra birinin de okuması içindir . Bu nedenle, kodunuzda anlaşılması zor birkaç satır varsa ve bunların anlaşılmasını kolaylaştıramazsanız, okuyucunun bu satırlar için yer tutucu olarak kullanması için bir yorum faydalı olacaktır. Okuyucu sadece genel özeni elde etmeye çalışırken, çok yararlı olabilir, ancak birkaç sorun var:

  • Yorumlar mutlaka doğru değildir, oysa kod ne yaparsa onu yapar. Bu yüzden okuyucu bunun sözünü alıyor ve bu ideal değil.
  • Okuyucu henüz kodun kendisini anlamıyor, bu yüzden daha sonra geri dönene kadar değiştirmeye veya yeniden kullanmaya yetkin değil. Hangi durumda onu okuyorlar?

İstisnalar var, ancak çoğu okuyucu kodun kendisini anlamalı. Yorumlar, değiştirilmemelerine yardımcı olmak için yazılmalıdır, bu nedenle genel olarak yorumların "neden yaptığınızı" söylemesi önerilir. Önümüzdeki birkaç kod satırı için motivasyonu bilen bir okuyucu, ne yaptıklarını ve nasıl yaptıklarını görme konusunda daha iyi bir şansa sahip.


5
Yorumlar için faydalı bir yer: Bilimsel kodda, oldukça değişken olan ve çok sayıda değişkeni içeren hesaplamalar yapabilirsiniz. Programcının aklı için, değişken isimleri gerçekten kısa tutmak mantıklıdır, böylece isimleri değil matematiğe bakabilirsiniz. Ancak bu, okuyucu için anlamayı gerçekten zorlaştırıyor. Dolayısıyla, neler olup bittiğine dair kısa bir açıklama (veya daha iyisi, bir dergi makalesinde veya benzerindeki bir denkleme referans) gerçekten yardımcı olabilir.
naught101

1
@ naught101: evet, özellikle de atıfta bulunduğunuz yazı muhtemelen tek harfli değişken isimleri kullandığından. Bu aynı adları kullanırsanız kod aslında kağıt izleyin olmadığını görmek için genelde daha kolay, ama bu (o anlatılmış kendini açıklayıcı olma kod hedefi çatışma halinde bulunuyor kağıt tarafından yerine). Bu durumda, her ismin tanımlandığı ve gerçekte ne anlama geldiğini söyleyen bir yorum, anlamlı isimlerin yerini almaktadır.
Steve Jessop

1
Kodda belirli bir şeyi ararken (bu özel durum nerede ele alınır?), Yalnızca sonuçta yer olmadığını keşfetmek için kod paragraflarını okumak ve anlamak istemiyorum. Bir sonraki paragrafın ne yaptığını tek bir satırda özetleyen yorumlara ihtiyacım var. Bu şekilde, sorunumla ilgili kodun bölümlerini hızlıca bulacağım ve ilginç olmayan ayrıntıları atlayacağım.
Florian F

1
@FlorianF: geleneksel cevap, değişken ve işlev adlarının kabaca kodun ne hakkında olduğunu göstermesi gerektiği ve bu nedenle kesinlikle aradığınız şeyle ilgili olmayan şeyleri gözden geçirmenize izin vermesi gerektiğidir. Bunun her zaman başarılı olamayacağı konusunda hemfikirim ama o kadar güçlü bir şekilde aynı fikirdeyim ki, araştırmaya veya eksik okumaya yardımcı olmak için tüm kodların yorumlanması gerektiğini düşünüyorum . Ama haklısın, bu birisinin kodunuzu okuduğu (yasal olarak) bir durumdur ve yasal olarak bunu anlamak zorunda değildir.
Steve Jessop

2
@Snowman İnsanlar bunu değişken isimlerle yapabilirdi. ListOfApples değişkeninin bir muz listesi içerdiği bir kod gördüm. Birileri Elma listesini işleyen kodu kopyaladı ve değişken isimlerini değiştirmeden rahatsız etmeden Banana'ya uyarladı.
Florian F

5

Genellikle karmaşık şeyler yapmak zorundayız. Gelecekteki anlayışı için onları belgelemek kesinlikle doğru. Bazen bu belgeler için doğru yer, belgelerin kodla güncel tutulabileceği koddadır. Ancak kesinlikle ayrı belgeler dikkate alınarak değer. Bu aynı zamanda başkalarına sunmak, diyagramlar, renkli resimler vb. İçermek için daha kolay olabilir. O zaman yorum sadece:

// This code implements the algorithm described in requirements document 239.

hatta sadece

void doPRD239Algorithm() { ...

Elbette insanlar MatchStringKnuthMorrisPrattya encryptAESda ismindeki fonksiyonlardan memnunlar partitionBSP. Bir yorumda daha belirsiz isimler açıklanmaya değer. Ayrıca, bibliyografik veri ve algoritma uyguladığınız bir kağıda bağlantı ekleyebilirsiniz.

Bir algoritma karmaşık ve yeni ve açık değilse, yalnızca şirket içi dolaşımda olsa bile kesinlikle bir belgeye değer. Kaybolduğundan endişeleniyorsanız, belgeyi kaynak kontrolünde kontrol edin.

Bürokratik kadar algoritmik olmayan başka bir kod kategorisi daha var. Başka bir sistem için parametreler ayarlamanız veya başka birinin hatalarıyla birlikte çalışmanız gerekir:

/* Configure the beam controller and turn on the laser.
The sequence is timing-critical and this code must run with interrupts disabled.
Note that the constant 0xef45ab87 differs from the vendor documentation; the vendor
is wrong in this case.
Some of these operations write the same value multiple times. Do not attempt
to optimise this code by removing seemingly redundant operations.
*/

2
Ben işlevleri / yöntemleri kendi iç algoritma sonra, yöntem elbette, bir iç endişe edilmelidir kullanılan çoğu zaman kullanılan yöntem ile fonksiyonun üst belgelemek adlandırma karşı iddia ediyorum, ama demiyoruz doPRD239Algorithmbana söyleyen algoritmaya bakmak zorunda kalmadan fonksiyon hakkında hiçbir şey, sebep MatchStringKnuthMorrisPrattve encryptAESiş yaptıkları şeyin açıklamasıyla başlamaları, daha sonra metodolojinin bir açıklaması ile devam etmeleridir.
scragar

5

Okudum ama orada nerede unutmak olduğunu kodunuzda görünmelidir ve yorum olarak ne görünmelidir neyi arasında keskin ve net bir çizgi.

Niyetinizi yorumlamanız gerektiğine inanıyorum , algoritmanızı değil . Yani , ne yapmak istediğinizi yorumlayın, ne yaptığınıza değil .

Örneğin:

// The getter.
public <V> V get(final K key, Class<V> type) {
  // Has it run yet?
  Future<Object> f = multitons.get(key);
  if (f == null) {
    // No! Make the task that runs it.
    FutureTask<Object> ft = new FutureTask<Object>(
            new Callable() {

              public Object call() throws Exception {
                // Only do the create when called to do so.
                return key.create();
              }

            });
    // Only put if not there.
    f = multitons.putIfAbsent(key, ft);
    if (f == null) {
      // We replaced null so we successfully put. We were first!
      f = ft;
      // Initiate the task.
      ft.run();
    }
  }
  try {
    /**
     * If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
     * then you are trying to get from your Multiton in your creator.
     *
     * Cannot check for that without unnecessarily complex code.
     *
     * Perhaps could use get with timeout.
     */
    // Cast here to force the right type.
    return (V) f.get();
  } catch (Exception ex) {
    // Hide exceptions without discarding them.
    throw Throwables.asRuntimeException(ex);
  }
}

Burada, her adımın ne yaptığını belirtmek için hiçbir çaba yoktur, tek ifade ettiği şey ne yapılması gerektiğidir .

Not: Bahsettiğim kaynağı buldum - Kod Yazma Korku: Kod Nasıl Anlatıyor, Yorumlar Nedenini Söyler


8
İlk yorum: Henüz çalıştı mı? Ne kaçtı mı? Diğer yorumlar için aynı. Kodun ne yaptığını bilmeyen biri için bu işe yaramaz.
gnasher729

1
@ gnasher729 - bağlam dışına çekildi hemen her açıklama yararsız olacaktır - bu kod belirten yorumlar ekleyerek bir tanıtımdır niyet girişiminde ziyade tarif . Senin için hiçbir şey yapmadığı için özür dilerim.
OldCurmudgeon

2
Bu kodun sağlayıcısının bir içeriği olmaz. Kodun ne yaptığını anlamak özellikle zor değil, ancak yorumlar yardımcı olmuyor. Yorum yazarsanız, zaman ayırın ve yazarken konsantre olun.
gnasher729

BTW - Çalıştırdı henüz yorumuna atıfta bulunuyor Futureve get()bunu takiben bir kontrolün daha önce nullçalışıp Futureçalışmadığını tespit etmeyi kontrol ediyor - işlemin amacını doğru bir şekilde belgeliyor olduğunu gösteriyor .
OldCurmudgeon 5:14

1
@OldCurmudgeon: Cevabınız düşündüğüm şeye yeterince yakın, bu yorumu sizin amacınıza örnek olarak ekleyeceğim. Temiz kodu açıklamak için bir yoruma gerek duyulmasa da, bir yorum neden kodlamanın başka bir yoldan yapıldığını açıklamak için iyidir. Sınırlı deneyimlerime göre, yorumlar genellikle kodun üzerinde çalıştığı verilerin kümesini veya kodun uygulamak istediği iş kurallarını açıklamak için kullanışlıdır. Bir hatayı düzeltmek için eklenen kodun yorumlanması iyi bir örnektir; bu hata, verilerle ilgili bir varsayımın yanlış olması nedeniyle gerçekleştiyse.
Randall Stewart,

4

Ama hepimiz biliyoruz ki bu yeterli değil.

Gerçekten mi? Ne zamandan beri?

İyi isimler içeren iyi tasarlanmış kod, çoğu durumda yeterli değildir. Yorumları kullanmaya karşı argümanlar iyi bilinmektedir ve belgelenmiştir (dediğiniz gibi).

Ancak bunlar kurallardır (başka herhangi bir şey gibi). Nadir bir durumda (deneyimlerime göre, yaklaşık 2 yılda bir), daha küçük okunaklı işlevlere (performans veya uyum ihtiyaçları nedeniyle) yeniden yerleştirildiğinde daha kötü olacağına dair daha sonra ilerlemeye devam ediyor - olayın gerçekte ne olduğunu açıklayan uzun bir açıklama yapıyor (ve neden en iyi uygulamaları ihlal ediyorsunuz).


7
Yeterli olmadığını biliyorum.
Florian F

2
Ne zamandan beri? Görünüşe göre, bunun cevabını zaten biliyorsun. “İyi tasarlanmış iyi tasarlanmış kod , vakaların çoğunda fazlasıyla yeterli .” Bu nedenle, az sayıdaki davada muhtemelen yeterli değildir, bu da sorucunun tam olarak sorduğu şeydir.
Ellesedil

3
Her iki yılda bir, birkaç defadan fazla yorumda bulunmasını istediğim diğer insanların kodunu deşifre etmeye çalışıyorum.
Ogre Mezmurlar33

@ OgrePsalm33 - Küçük metodları var mı ve iyi isimler mi kullanıyorlar? Kötü kod, yorumlarından bağımsız olarak kötü.
Telastyn

2
@Telastyn Ne yazık ki, büyük bir kod tabanında çalışırken, "küçük" yöntemler ve "iyi" adlar her geliştiriciye özneldir (bu nedenle bu konuda iyi bir yorumdur). Flarbigan grafik işleme algoritması kodunu 7 yıl boyunca yazan bir geliştirici, kendisi ve benzer geliştiricileri için tamamen net bir şeyler yazabilir, ancak son 4 yılını Perbian ızgara altyapısı kodunu geliştirmek için harcayan yeni adama şifreli olur. Sonra, 2 hafta sonra, Flarbigan uzmanı istifa etti.
Ogre Psalm33

2

Kodun temel amacı, bir bilgisayara bir şeyi yapmasını emretmektir, bu nedenle iyi bir yorum asla iyi kodun yerine geçmez, çünkü yorumlar yürütülemez.

Söylendiği gibi, kaynaktaki yorumlar diğer programcılar için (sizin de dahil) bir dokümantasyon şeklidir. Yorumlar, her adımda kodun yaptığından daha fazla soyut sorunla ilgiliyse, ortalamadan daha iyi yapıyorsunuzdur. Bu soyutlama seviyesi, kullandığınız araca göre değişir. Montaj dili yordamlarına eşlik eden yorumlar, genellikle bu APL'den daha düşük bir "soyutlama" seviyesine sahiptir A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕. Bunun muhtemelen çözülmesi amaçlanan sorunla ilgili bir yorum yapabileceğini düşünüyorum, hmmm?


2

Kod önemsiz ise, açıklayıcı bir yoruma gerek yoktur. Eğer kod önemsiz değilse, açıklayıcı yorum önemsiz de olacaktır.

Şimdi, önemsiz olmayan doğal dille ilgili sorun, çoğumuzun onu okumakta veya yazmakta pek iyi olmadığımızdır. Yazılı iletişim becerilerinizin mükemmel olduğundan eminim, ancak yine de yazılı dili daha az kavrayabilen biri sözcüklerinizi yanlış anlayabilir.

Yanlış anlaşılmayan doğal bir dil yazmak için çok uğraşırsanız, yasal bir belge gibi bir şeyle karşılaşırsınız (ve hepimizin bildiği gibi bunların koddan daha ayrıntılı ve anlaşılması zor).

Kod, mantığınızın en özlü açıklaması olmalıdır ve kodunuzun anlamı hakkında çok fazla tartışma olmamalıdır, çünkü derleyici ve platformunuz son sözdedir.

Şahsen ben asla bir yorum yazmamalı demem. Yalnızca kodunuzun neden bir yoruma ihtiyaç duyduğunu ve bunu nasıl düzeltebileceğinizi düşünmelisiniz. Buradaki cevaplarda ortak bir tema gibi görünüyor.


Tam olarak "Bir insan, bir işlemi İngilizce önemsiz olmadığı sürece aynı anlama sahip bir kod parçasını anlayabildiğinden daha hızlı anlayabilir" ifadesine katılmıyorum. her zaman daha az belirsiz ve daha özlüdür.
stephenbayer

0

Henüz belirtilmeyen bir nokta, bir dilin çok amaçlı olarak belirli bir sözdizimi kullanması durumunda, bir kod parçasının ne gibi bir şey yapabileceğini kesin olarak yorumlamaktır. Örneğin, tüm değişkenlerin tür olduğunu varsayarsak float, şunları göz önünde bulundurun:

f1 = (float)(f2+f3); // Force result to be rounded to single precision
f4 = f1-f2;

Açıkça bir floatşekilde a'nın dökülmesinin etkisi float, sonucu tek bir kesinliğe yuvarlamak için zorlamaktır; Bu nedenle yorum, yalnızca kodun ne yaptığını söylemek olarak görülebilir. Öte yandan, bu kodu aşağıdakilerle karşılaştırın:

thing.someFloatProperty = (float)(f2*0.1); // Divide by ten

Burada, dökümün amacı, derleyicinin doğru hesaplama için en verimli şekilde ciyaklanmasını önlemektir (f2 / 10) [0.1f ile çarpmaktan daha doğrudur ve çoğu makinede 10.0f ile bölmekten daha hızlıdır].

Yorum yapılmazsa, eski kodu inceleyen biri, oyuncu adayının yanlışlıkla derleyicinin cızırtılığını engellemesinin gerekli olacağına ve gerekmediğine dair bir inançla eklendiğini düşünüyor olabilir. Aslında, oyuncu seçimi, tam olarak dil spesifikasyonunun söylediği şeyi yapma amacına hizmet eder: Yuvarlamanın sonucu daha yüksek hassasiyette tutmaktan daha pahalı olduğu makinelerde bile, hesaplamanın sonucunu yuvarlanmaya zorlar. Bir oyuncu kadrosunun floatfarklı anlam ve amaçlara sahip olabileceği göz önüne alındığında, belirli bir senaryoda hangi anlamın amaçlandığını belirten bir yorum yapmak, gerçek anlamın niyet ile aynı hizada olduğunu açıkça göstermeye yardımcı olabilir.


İkinci örneğe bakarak J. Random Programmer'ın, sabit programın iyi bir sebepten dolayı 0.1 yazıldığını fark etmeyeceğinden emin değilim, orijinal programlayıcı bir 'f' yazmayı unuttu.
David K

Özellikle hata ayıklama sırasında hiçbir şeyin iyi bir nedenden dolayı yapıldığını varsaymazsınız.
gnasher729

@DavidK: İkinci örnek kodumun amacı, ilk kod parçasıyla karşılaştırmaktı. İkinci kod parçasında, programcının amacı muhtemelen yapabileceği someFloatPropertyen doğru temsile sahip olmaktır f2/10; Böylece, ikinci almanın temel amacı basitçe kodun derlenmesidir . Bununla birlikte, ilk örnekte, operalar zaten olduğundan, oyuncu kadrosu normal amacı için (bir derleme zamanı türünü diğerine değiştirmek) açıkça gerekli değildir float. Yorum dökme açıkça belirten yarar olduğu ikincil bir amaç (yuvarlama) için gerekli.
supercat

(float)İkinci örnekte oyuncu kadrosu hakkında herhangi bir yorum yapmanız gerekmediği fikrine katılıyorum . Soru değişmez sabitle ilgilidir 0.1. Neden yazacağımızı (metnin bir sonraki paragrafında) açıkladınız 0.1: "0.1f ile çarpmaktan daha doğru". Ben öneriyorum bu açıklamada olmalıdır kelimelerdir.
David K,

@DavidK: Eğer 0.1f'nin kabul edilemez derecede kesin olmadığını ve eğer kesinliğin kaybının kabul edilebilir olacağını ve aslında 0.1f'nin maddi olarak 0.1'den daha hızlı olacağını bilseydim 0.1f'yi kullanırsam kesinlikle şunu eklerdim . Bunların hiçbirinin doğru olmadığını bilmezsem, tercih edilen kodlama alışkanlığım double, değeri float[gösterilemeyen açık yüzer yayınlar için can sıkıcı diller gerektiren dillerde olsa tembellik olarak ifade edilemeyecek olan sabitler veya ara hesaplamalar için kullanmak olacaktır. floathız için değil sabit kullanımı, sıkıntıyı en aza indirmek için kullanmak olabilir .
supercat

-1

Kodun ne yaptığını açıklayan yorumlar bir çoğaltma şeklidir. Kodu değiştirirseniz ve yorumları güncellemeyi unutursanız, karışıklığa neden olabilir. Onları kullanma, sadece mantıklı kullan, demiyorum. Bob Amca maxim'e abone oldum: "Sadece kodun söyleyemediği şeyleri yorumla".

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.