Kod açıklamalarını ve sınıf belgelerini temizleme


83

Yeni meslektaşlarımla yorum yapma konusunda bazı tartışmalar yapıyorum. İkimiz de Temiz Kod'u seviyoruz ve satır içi kod yorumlarından kaçınılması ve sınıf ve yöntem adlarının yaptıklarını ifade etmek için kullanılması gerektiği konusunda gayet iyiyim.

Ancak, ben sınıfın amacını açıklamak çalışır ve aslında ne temsil küçük sınıf özetleri ekleyerek büyük bir hayranıyım öncelikle böylece onun bakımı kolaydır tek sorumluluk ilkesi deseni. Ayrıca, yöntemin ne yapması gerektiğini açıklayan yöntemlere tek satırlık özetler eklemeye alışkınım. Tipik bir örnek basit yöntemdir

public Product GetById(int productId) {...}

Aşağıdaki yöntem özetini ekliyorum

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary

Yöntemin boş döndürdüğü gerçeğinin belgelenmesi gerektiğine inanıyorum. Bir yöntemi çağırmak isteyen bir geliştiricinin, yöntemin null değerini döndürdüğünü veya bir istisna attığını görmek için kodumu açması gerekmemelidir. Bazen bir arabirimin bir parçası olduğundan, geliştirici hangi temel kodun çalıştığını bile bilmiyor mu?

Ancak meslektaşlarım bu tür yorumların " kod kokusu " ve "yorumlar her zaman başarısız" olduğunu düşünüyor ( Robert C. Martin ).

Yorum yazmadan bu tür bilgileri ifade etmenin ve aktarmanın bir yolu var mı? Robert C. Martin'in büyük bir hayranı olduğum için biraz kafam karıştı. Özetler yorumlar ile aynı mı ve bu nedenle her zaman başarısız mı?

Bu satır içi yorumlar hakkında bir soru değil.


38
Robert Martin "Yorumlar her zaman başarısız olur" mu dedi? Öyleyse uçurumdan uzak bir uçurum ve bir tutam tuzla alınmalıdır. (Evet, mesajlarını iletmek için retorik amaçlarla böyle yazdığını biliyorum. Benim açımdan, sen de öyle yapmalısın .)
Kilian Foth

18
Bob Amca'nın kitapları 1
kg'lık bir

6
Robert Martin'i izliyorsanız, boş durumda olan belgeler bir test olmalıdır. Yani, hangi durumda yöntemin null döndüğünü gösteren bir test yaptırmalısınız. Alternatif olarak, bu Java olduğu için, @Null'lu bir açıklama da yorumdan daha iyi olacaktır.
Martin Epsz

15
@Bjorn Bir Temiz Kod kopyasına sahibim ve bir kereden fazla kapsayacak şekilde kapağı okudum. Evet, Bob Amca kodun kendi kendini belgelendirmesini tercih ediyor, ancak kitapta kendi kodunda birden fazla yorum örneği var . Mesele şu ki, bir yorum yazmak zorunda kalırsanız, yorum eklemek yerine kodu değiştirmeyi gerçekten deneyin, ancak yorumları tamamen reddetmeyin (hatta satır içi yorumlar bile).

6
Yöntem TryGetById olarak adlandırılmalı ve yorum kaldırılmalıdır.
usr

Yanıtlar:


116

Diğerlerinin de söylediği gibi, API belgeleyen yorumlar ve satır içi yorumlar arasında bir fark vardır. Benim açımdan ana fark, satır içi bir yorumun kodun yanında okunması , dokümantasyon yorumunun ise yorumda bulunanın imzası ile birlikte okunmasıdır .

Bunu göz önüne alarak, aynı KURU ilkesini uygulayabiliriz . Yorum, imza ile aynı şeyi mi söylüyor? Örnekinize bakalım:

Bir ürünü kimliği ile alır

Bu bölüm sadece isim GetByIdartı dönüş türünden zaten gördüğümüzü tekrarlıyor Product. Aynı zamanda "alma" ile "alma" arasındaki farkın ne olduğu ve bu ayrım üzerinde yorum ile ilgili taşıma kodu arasındaki soruyu da gündeme getirmektedir. Bu yüzden gereksiz ve biraz kafa karıştırıcı. Eğer bir şey varsa, yorumun ikinci kısmı için gerçekten faydalı bir yoldan geçiyor:

Ürün bulunamadıysa null değerini döndürür.

Ah! Bu kesinlikle imzadan kesinlikle emin olamadığımız ve faydalı bilgiler sağlayan bir şey.


Şimdi bunu bir adım daha ileri götürün. İnsanlar yorumlarla bahsederken kod kokuyor olarak, soru kodu olup olmadığı değil , olduğu gibi Yorumunuz bilgileri ifade etmek, kod iyi yazılmış olabileceğini belirtip belirtmediğini bir yorum ihtiyacı var ama. "Kod kokusu" ne anlama geliyor - bu "bunu yapma!" Anlamına gelmez, "bunu yapıyorsanız, bir sorun olduğuna dair bir işaret olabilir" anlamına gelir.

Eğer meslektaşlarınız size null hakkındaki bu yorumun bir kod kokusu olduğunu söylerlerse, onlara basitçe sormalısınız: "Tamam, bunu nasıl ifade etmeliyim?" Uygun bir cevapları varsa, bir şey öğrendiniz. Olmazsa, muhtemelen şikayetlerini ölü olarak öldürür.


Bu özel durumla ilgili olarak, genellikle boş olan meselenin zor olduğu bilinmektedir. Kod üslerinin gardiyan cümleleriyle karıştırılmasının bir nedeni var, neden boş denetimlerin neden kod sözleşmeleri için popüler bir önkoşulduğunu, neden boşluğun varlığına "milyar dolarlık hata" olarak adlandırıldığını açıklıyor. Çok fazla uygun seçenek yok. Yine de popüler olanlardan biri C # 'da bulundu Try...:

public bool TryGetById(int productId, out Product product);

Diğer dillerde, orada bulunabilecek Optionalveya Maybebulunmayacak bir sonucu belirtmek için bir türün (genellikle veya buna benzer bir şey denir) kullanılması deyimsel olabilir:

public Optional<Product> GetById(int productId);

Dolayısıyla, bir şekilde, bu yorum karşıtı duruş, bizi bir yerlere taşıdı: en azından bu yorumun bir kokuyu temsil edip etmediğini ve bizim için hangi alternatiflerin olabileceğini düşündük.

Biz olup olmayacağı aslında orijinal imza üzerinde bunları tercih bambaşka bir tartışma, ama biz en azından bir ürün bulunursa ne olur kod yerine yorumlar aracılığıyla ifade ettikleri için seçenekler vardır. Meslektaşlarınızla, bu seçeneklerden hangisinin daha iyi olduğunu ve niçin daha iyi olduğunu düşündüklerini konuşmalı ve yorumlarla ilgili dogmatik ifadelerin ötesinde ilerlemeye yardımcı olmalısınız.


9
Veya Linqbir -eşdeğer Try..., ...OrDefaultdönmek, default(T)fıkra boş sonuca yol açacak eğer.
Bart van Nierop,

4
Satır içi kod açıklamaları ve dökümantasyon yorumları ile verilen örnekler arasındaki farkınızı gerçekten takdir ediyorum :)
Rachel

2
Bir işlevin muhtemel geri dönüş değerleri imzası ile açıkça anlaşılmalıdır. TryGetValueDesen C # bunu yapmanın makul yoldur, ancak en işlevsel diller eksik bir değeri temsil daha iyi bir yol var. Burada daha fazla okuyun
AlexFoxGill

2
@BenAaronson: Eğer biri kovaryansı destekleyebilecek jenerik bir arayüze sahip olmak isterse, T TryGetValue(params, ref bool success)herhangi bir T tipi için ya T TryGetValue(params)da boş gösterge hatası olan T tipi için kullanılabilir, ancak TryGetXXgeri dönen kalıp boolkovaryansla uyumlu değildir.
supercat,

6
Java 8'de, Optional<Product>yöntemden döndürülen bir Ürün olmayabileceğini belirtmek için bir işaretini geri döndürebilirsiniz .
Wim Deblauwe

102

Robert C. Martin alıntı bağlam dışına alınmıştır. İşte biraz daha fazla bağlamda alıntı:

Hiçbir şey iyi yerleştirilmiş bir yorum olarak bu kadar yardımcı olamaz. Hiçbir şey bir modülü anlamsız dogmatik yorumlardan daha fazla tutamaz. Hiçbir şey yalanları ve yanlış bilgiyi yayan eski bir kabarık yorum kadar zarar veremez.

Yorumlar, Schindler'in Listesi gibi değildir. "Saf iyi" değiller. Gerçekten de, yorumlar en iyi ihtimalle gerekli bir kötülüktür. Programlama dillerimiz yeterince açıklayıcı olsaydı ya da bu dilleri niyetimizi açık bir şekilde kullanma yeteneğine sahip olsaydık, yorumlara çok fazla ihtiyacımız olmazdı - belki de hiç.

Yorumların doğru kullanımı, kendimizi kodda ifade etmememizdeki tazminatı telafi etmektir. Ben başarısızlık kelimesini kullandığımı unutmayın. Bunu kastettim. 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.

Dolayısıyla, kendinizi bir yorum yazmanız gereken bir pozisyonda bulduğunuzda, düşünün ve tabloları çevirip kodunuzu ifade etmenin bir yolu olmadığını görün. Kendini kodda her ifade ettiğinde, kendini arkaya koymalısın. Her yorum yazdığınızda, ifade yeteneğinizin başarısızlığını hissetmeniz ve hissetmeniz gerekir.

( Buradan kopyalandı , ancak orijinal alıntı Temiz Kod'dan: Çevik Yazılım İşçiliğinin El Kitabı )

Bu teklifin "Yorumlar her zaman başarısız olur" olarak nasıl azaldığı, bazı insanların bağlamdan nasıl mantıklı bir teklif alacağı ve onu aptal dogmaya çevireceğine iyi bir örnektir.


API belgelerinin (javadoc gibi), kullanıcının kaynak kodunu okumak zorunda kalmadan kullanabilmesi için API'yi belgelemesi gerekir . Yani bu durumda dokümantasyon gereken yöntem ne yaptığını açıklar. Şimdi, "Bir ürünü kimliğine göre alır" ifadesinin gereksiz olduğunu iddia edebilirsiniz, çünkü yöntem adıyla zaten belirtilmiştir, ancak nulliade edilebilecek bilgilerin belgelenmesi kesinlikle önemlidir, çünkü bu, hiçbir şekilde açık değildir.

Yorumun gerekliliğinden kaçınmak istiyorsanız null, API'yi daha belirgin hale getirerek, temel sorunu ( geçerli bir dönüş değeri olarak kullanılan) kaldırmanız gerekir . Örneğin Option<Product>, bir tür geri döndürebilirsiniz , bu nedenle tür imzası, ürünün bulunamaması durumunda ne iade edileceğini açıkça belirtir .

Ancak, her durumda, bir API'yi yalnızca yöntem adları ve tür imzaları aracılığıyla tam olarak belgelemek gerçekçi değildir. Kullanıcının bilmesi gereken açık olmayan ek bilgiler için doc-comment kullanın. API belgelerini DateTime.AddMonths()BCL’den alın:

AddMonths yöntemi, artık ay ve yılı hesaplar; artık yıl ve aydaki gün sayısını hesaba katar ve sonra da DateTime nesnesinin gün bölümünü ayarlar. Eğer sonuçlanan gün sonuçta geçen ay için geçerli bir gün değilse, sonuçta kalan ayın son geçerli günü kullanılır. Örneğin, 31 Mart + 1 ay = 30 Nisan. Elde edilen DateTime nesnesinin günün saati bölümü bu örnekle aynı kalır.

Bunu sadece yöntem adı ve imzasını kullanarak ifade edemezsiniz! Elbette sınıf belgeleriniz bu seviyede bir ayrıntı gerektirmeyebilir, sadece bir örnektir.


Satır içi yorumlar da fena değil.

Kötü yorumlar kötü. Örneğin, yalnızca kodda önemsiz olarak görülebilecekleri açıklayan yorumlar için, klasik örnek şöyledir:

// increment x by one
x++;

Bir değişkeni veya yöntemi yeniden adlandırarak veya kodu başka bir şekilde yeniden yapılandırarak netleştirilebilecek bir şeyi açıklayan yorumlar kod kokusudur:

// data1 is the collection of tasks which failed during execution
var data1 = getData1();

Bunlar Martin’in aleyhine yazdığı yorumlar. Yorum, net kod yazılmamasının bir belirtisidir - bu durumda değişkenler ve yöntemler için kendi kendini açıklayıcı isimler kullanmak. Yorumun kendisi elbette sorun değil, sorun kodu anlamak için yoruma ihtiyacımız var.

Ama yapılan yorumlar gereken kod, örneğin açık değil her şeyi açıklamak için kullanılan neden kodu belli olmayan bariz bir şekilde yazılır:

// need to reset foo before calling bar due to a bug in the foo component.
foo.reset()
foo.bar();

Aşırı sarsılmış bir kod parçasının ne yaptığını açıklayan yorumlar aynı zamanda bir kokudur, ancak düzeltme yorumların yasaklanmasına yol açmaz, düzeltme kodun düzeltilmesidir! Gerçek anlamda, basit bir kod gerçekleşir (umarım sadece bir refraktöre kadar geçici olarak) ancak sıradan bir geliştirici ilk kez mükemmel bir temiz kod yazmaz. Dolambaçlı kod buna yaptığından daha açıklayan bir yorum yazmak için çok daha iyidir durumda değil görüş bildirmek. Bu yorum ayrıca daha sonra yeniden ateşlenmeyi kolaylaştıracaktır.

Bazen kod kaçınılmaz olarak karmaşıktır. Karmaşık bir algoritma olabilir veya performans nedenleriyle açıklıktan ödün veren netlik olabilir. Yine yorumlar gerekli.


13
Orada kodunuzu sadece bir durumu ele alır vaka da var olan karmaşık ve basit kod halledebilir.
gnasher729

6
İyi nokta, Gnasher. Bu, performans için bazı kod parçalarını optimize etmeniz gerektiğinde sıklıkla görülür.
JacquesB

9
x++Eğer bir yorum bile "eğer birer birer x artırma, UINT32_MAX ise etrafta sarma" gibi bir şey olsa iyi olabilir; Dil belirtimini bilen herkes bir artışın arttırılacağını bilir uint32_t, ancak yorum yapılmadan böyle bir sarmanın uygulanan algoritmanın beklenen bir parçası olup olmadığını bilemez .
supercat,

5
@ l0b0: Umarım şaka yapıyorsunuzdur!
JacquesB

9
@ l0b0 Geçici kod diye bir şey yoktur. İşbu sonuçtan memnun kaldığı ve düzeltmek için finansmanı onaylamadığı için kod hiçbir zaman yeniden kırılmaz. Bundan beş yıl sonra, bazı küçük geliştiriciler bu kodu görecek, artık Bugtrocity v9 ile değiştirdiğinizden beri WizBug 4.0 kullanmıyorsunuz, bu yüzden "Bug123" onun için hiçbir şey ifade etmiyor. Şimdi bunun ne kadar kalıcı bir kod olması gerektiğini düşünüyor ve tüm kariyeri boyunca korkunç bir geliştirici olduğunu düşünüyor. Çocukları düşün. Geçici kod yazmayın.
corsiKa

36

Arasında bir fark yoktur kodunuzu yorumlama ve kodunuzu belgeleyen .

  • Kodu daha sonra korumak için yorumlar gerekir, bu kodun kendisini değiştirmesidir.

    Yorumlar gerçekten de sorunlu olarak algılanabilir. Aşırı nokta onlar söylemek olurdu hep kodunuzu (anlamak çok zor kod) içinde veya dil (yeterince anlamlı olması mümkün dili içinde ya bir soruna işaret; örneğin aslında yöntem döndürür asla nullifade edilebilir C # 'daki Kod sözleşmeleri yoluyla, ancak PHP ile kodla ifade etmenin bir yolu yoktur).

  • Geliştirdiğiniz nesneleri (sınıflar, arayüzler) kullanabilmek için belgeler gerekir. Hedef kitle farklı: burada kodunuzu koruyacak ve burada konuştuğumuz dili değiştirecek olan insanlar değil, ancak kullanması zor olan kişiler .

    Kodun yeterince açık olması nedeniyle dokümantasyonun kaldırılması deliliktir, çünkü dokümantasyon özellikle burada binlerce satır kodunu okumak zorunda kalmadan sınıfları ve arayüzleri kullanmayı mümkün kılar .


Evet, ama Martin’in hedefinin en azından bir kısmı, modern geliştirme uygulamalarında, testlerin kodun kendisi değil, dokümantasyon olduğudur. Kodun BDD tarzı bir test sistemi, örneğin spekülasyon ile test edildiğini varsayarsak, testlerin kendileri metodun davranışının doğrudan okunabilir bir açıklamasıdır ("GetById geçerli bir ürünün kimliği ile çağrıldığında bir ürün veri tabanı verilir. GetById geçersiz bir ürün kimliği ile çağrıldığında uygun Ürün nesnesi [...] döndürülür, sonra null döndürülür "ya da bunun gibi bir şey).
Jules

13

Görünen o ki, meslektaşın kitap okuyor, söylediklerini alıyor ve öğrendiklerini düşünmeden ve bağlamı gözetmeden uyguluyor.

İşlevin ne yaptığıyla ilgili yorumunuz, uygulama kodunu atabileceğiniz şekilde olmalı, işlevin yorumlarını okudum ve yanlış bir şey yapmadan uygulamanın yerine yazdırabilirim.

Yorum bana bir istisna atılıp atılmadığını ya da sıfırın döndürülmediğini söylemezse, bunu yapamam. Ayrıca, yorum size bir istisna atılıp atılmadığını veya sıfırın döndürülüp döndürülmediğini söylemezse , işlevi çağırdığınız her yerde, bir istisna atıldığında veya sıfır döndürüldüğünde kodunuzun doğru çalıştığından emin olmalısınız.

Yani meslektaşın tamamen yanlıştır. Ve devam edin ve bütün kitapları okuyun, ama kendiniz için düşünün.

PS. Satırınızı gördüm "bazen bir arayüzün parçası, bu yüzden hangi kodun çalıştığını bile bilmiyorsunuz." Sadece sanal fonksiyonlarda bile hangi kodun çalıştığını bilmiyorsunuz. Daha da kötüsü, eğer soyut bir sınıf yazarsanız, kod bile yoktur! Dolayısıyla, soyut işlevi olan bir soyut sınıfınız varsa, soyut fonksiyona eklediğiniz yorumlar , bir somut sınıf uygulayıcısının bunları yönlendirmesi gereken tek şeydir. Bu yorumlar aynı zamanda sınıfın bir kullanıcısına rehberlik edebilecek tek şey olabilir, örneğin tek sahip olduğunuz soyut bir sınıf ve somut bir uygulama getiren bir fabrika ise, ancak uygulamanın herhangi bir kaynak kodunu asla göremezsiniz. (Tabii ki bir uygulamanın kaynak koduna bakmamalıyım).


10 yıldır kod yorum yapmadım. Yorumlar şişmiş, çöp. Bugünlerde hiç kimse kod yazmıyor. İyi biçimlendirilmiş ve adlandırılmış kod, küçük modüller, ayrıştırma, vb. Konularına odaklanıyoruz. Testler, kodu atmanız durumunda hiçbir şeyin yanlış gitmemesini, yorum yapılmamasını sağlar. Testler size yazdığınız kodu nasıl kullandığınızı, nasıl çağırdığınızı ve neden ilk sırada bulunduğunu söyler. Çok eski bir okuldasın dostum test etmeyi ve kodu temizlemeyi öğrenmen gerekiyor.
PositiveGuy

12

Dikkate alınması gereken iki tür yorum vardır - kod sahibi kişiler tarafından görülebilenler ve dokümantasyon oluşturmak için kullananlar.

Bob Amca'nın bahsettiği yorumun türü, yalnızca kodu olan kişilerin görebileceği türdür. Savunduğu şey bir DRY şekli . Kaynak koduna bakan bir kişi için, kaynak kodu ihtiyaç duydukları belgeler olmalıdır. İnsanların kaynak koduna erişebildiği durumlarda bile, yorumlar her zaman kötü değildir. Bazen, algoritmalar karmaşıktır veya açık olmayan bir yaklaşıma neden girdiğinizi yakalamanız gerekir, böylece başkaları bir hatayı düzeltmeye veya yeni bir özellik eklemeye çalışırlarsa kodunuzu kırmaz.

Açıkladığınız yorumlar API dokümantasyonudır. Bunlar, uygulamanızı kullanan kişiler tarafından görülebilen, ancak kaynak kodunuza erişimi olmayan şeylerdir. Kaynak kodunuza erişseler bile, diğer modüller üzerinde çalışıyor olabilirler ve kaynak kodunuza bakmıyor olabilirler. Bu kişiler kodlarını yazarken bu belgelerin IDE'lerinde hazır bulundurulmasını yararlı bulabilirler.


Dürüst olmak gerekirse, DRY'yi kod + yorumlara başvurmayı hiç düşünmedim, ancak bu çok mantıklı geliyor. @ JacquesB'nin cevabındaki "artım X" örneğindeki gibi.

7

Bir yorumun değeri, eksi onu okumak ve / veya yoksaymak için gereken çabayı verdiği bilginin değeriyle ölçülür. Yani yorumu analiz edersek

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary>

değer ve maliyet için üç şey görürüz:

  1. Retrieves a product by its idişlevin adının ne dediğini tekrar eder, bu yüzden değeri yoktur. Silinmiş olmalı.

  2. returns null if no product was foundçok değerli bir bilgidir. Diğer kodlayıcıların işlevin uygulanmasına bakmak zorunda kalacağı süreleri azaltır. Kendisinin tanıttığı okuma maliyetinden daha fazla okuma tasarrufu sağladığından eminim. Kalmalı.

  3. Çizgiler

    /// <summary>
    /// </summary>
    

    hiçbir şekilde bilgi taşımayın. Yorumun okuyucusuna tamamen masraflıdırlar. Dokümantasyon üreticiniz ihtiyaç duyuyorsa haklı olabilirler, ancak bu durumda muhtemelen farklı bir dokümantasyon üreticisi hakkında düşünmelisiniz.

    Belge üreticilerinin kullanımının tartışmalı bir fikir olmasının nedeni budur: Genellikle sadece cilalanmış bir belge uğruna hiçbir bilgi taşımayan veya belirgin şeyleri tekrarlayan birçok ek yorum gerektirirler.


Diğer cevapların hiçbirinde bulamadığım bir gözlem:

Kodu anlamak / kullanmak için gerekli olmayan yorumlar bile çok değerli olabilir. İşte böyle bir örnek:

//XXX: The obvious way to do this would have been ...
//     However, since we need this functionality primarily for ...
//     doing this the non-obvious way of ...
//     gives us the advantage of ...

Muhtemelen bir sürü metin, kodu anlamak / kullanmak için tamamen gereksizdir. Ancak, kodun neden göründüğü gibi görünmesinin bir nedenini açıklar. Koda bakıp, neden açık şekilde yapılmadığını merak eden ve kodun neden ilk başta böyle yazıldığını anlayana kadar kodu yeniden düzenlemeye başlayacak insanları durduracak. Okuyucu, doğrudan yeniden ateşlemeye atlamayacak kadar zeki olsa bile, yine de en iyi şekilde kalması gerektiğini fark etmeden önce neden kodun neden göründüğünü bulmaya ihtiyaç duyuyorlar. Bu yorum tam anlamıyla çalışma saatlerinden tasarruf sağlayabilir. Dolayısıyla değer maliyetten daha yüksektir.

Aynı şekilde, yorumlar, tam olarak nasıl çalıştığı yerine bir kodun niyetini iletebilir. Ve genellikle kaybolan büyük resmi, kodun kendisinin dakikalık detayında boyayabilirler. Bu nedenle, sınıf yorumları lehine olma konusunda haklısınız. Sınıfın niyetini, diğer sınıflarla nasıl etkileşime girdiğini, nasıl kullanılması gerektiğini vb. Açıklarlarsa, sınıf yorumlarına en çok değer veririm. Ne yazık ki, bu tür yorumların büyük bir yazarı değilim.


2
Vay - doküman oluşturucunuzu değiştirin, çünkü ayrıştırmak için birkaç ekstra html satırı gerekiyor. Yapmayalım.
corsiKa

2
@corsiKa YMMV, ancak ben birincisi yorumlarda maliyetleri en aza indiren bir dokümantasyon oluşturucuyu tercih ederim. Tabii ki, gerçek kodla senkronize olmayan bir doxygen belgesinden çok iyi yazılmış bir başlık dosyasını da okumayı tercih ederim. Ama dediğim gibi, YMMV.
cmaster

4
Bir yöntemin adı amacını zekice tanımlasa bile, bu amacı doğal dil kullanarak tekrarlamak, okuduğunuz birinin, bu amacı izleyen herhangi bir uyarı ile ilişkilendirmesini kolaylaştırabilir. Adında anlatılanların düzeltilmesi, değer düşük olsa bile, maliyetin de düşük olacağı kadar kısa olacaktır. Bu yüzden gönderinizin ilk bölümüne katılmıyorum. İkinci kısım için ise +1. Değerlendirilen ve reddedilen alternatif yaklaşımların belgelenmesi son derece değerli olabilir, ancak bu bilgilere nadiren hak ettiği dikkat gösterilerek verilir.
supercat

GetByIdsoruyu gündeme getirir, kimliği nedir ve aynı zamanda nereden geldiğini de. Dokümantasyon yorumu, geliştirme ortamının bu sorulara cevap göstermesini sağlamalıdır. Belge modülünün yorumlarında başka bir yerde açıklanmadığı sürece, neden bir kişinin kimliği aldığını anlatan bir yer de olacaktır.
hyde

Darbe, temiz kod (kendi kendini tanımlayan), TDD (sık sık geri bildirim alma ve sık sık tasarımınız hakkında geri bildirim alma) ve testler (size güven ve belge davranışı verir) kuralları! Testler insanlar testler. Buradaki hiç kimse bunun hakkında konuşmuyor. uyanmak
PositiveGuy

4

Belirtilmemiş kod hatalı kod. Yaygın (evrensel değilse) bir efsanedir, bu kodun İngilizce dediği gibi okunabilmesi de mümkündür. Zaman ve çaba harcayan en önemsiz koddan başka herhangi bir şey için yorumlanmalıdır. Ayrıca, herkes herhangi bir dili okuma ve yazma konusunda farklı bir kabiliyet seviyesine sahiptir. Yazar ile okuyucunun kodlama stilleri ve yetenekleri arasındaki farklar, doğru yorumlamanın önündeki güçlü engellerdir. Ayrıca yazarın niyetini kodun uygulanmasından türetebileceğiniz bir efsanedir. Tecrübelerime ek yorumlar eklemek nadiren yanlıştır.

Robert Martin ve diğ. "kötü bir koku" olarak kabul et, çünkü kod değiştirilmiş ve yorum yapmamış olabilir. Bunun iyi bir şey olduğunu söylüyorum (aynı şekilde, kullanıcıyı sızıntılara karşı uyarmak için ev gazına "kötü bir koku" eklendiği gibi). Yorumları okumak, size gerçek kodu yorumlamak için yararlı bir başlangıç ​​noktası verir. Eşleşirlerse, koda olan güveni arttırmış olursunuz. Eğer farklılarsa, bir uyarı kokusu tespit ettiniz ve daha fazla araştırma yapmanız gerekiyor. Kötü kokunun tedavisi kokuyu gidermek değil, sızıntıyı kapatmak içindir.


2
Akıllı bir yazar olduğunuz ve metnin akıllı bir izleyici kitlesinin yararına olduğu; Çizgiyi sağduyulu kullanarak çizersiniz. Açıkçası, örnek olarak, aptalca bir durum söz konusudur, ancak bu, kodun bu noktada neden i ++ içerdiğini açıklamak için çok iyi bir neden olamayacağı anlamına gelmez.
Vince O'Sullivan

8
i++; // Adjust for leap years.
Vince O'Sullivan

5
“Robert Martin ve ark., Bunu“ kötü bir koku ”olarak kabul ediyorlar çünkü kodun değişip yorum yapmadığı söylenebilir.” Bu sadece kokunun bir parçası. Kokunun en kötüsü, programcının kodu daha açıklayıcı bir şekilde yazmaya çalışmamaya karar verdiği ve bunun yerine yorum ile "sızıntıyı mühürlemeyi" seçtiği fikrinden geliyor. Onun iddiası, "// artık yıllar için ayarla" yorumunu tokatlamak yerine, muhtemelen kodun kendisinde (veya benzer bir şekilde) "adjustForLeapYears ()" yöntemine sahip olması gerektiğidir. Belgeler artık yıl mantığını kullanan testler şeklinde gelir.
Eric King,

3
Tek bir kod satırının yerine bir yorum yazmanın yerine bir yöntem çağrısı eklemeyi düşünürdüm, çünkü özellikle yöntemin adı aslında bir kod parçasını etiketleyen ve daha iyi dokümantasyon doğruluğu garantisi olmayan bir yorumdur. (Eğer bu çizgi iki veya daha fazla yerde ortaya çıkarsa, o zaman bir yöntem çağrısı yapmak elbette tam olarak doğru çözüm olacaktır.)
Vince O'Sullivan

1
Nedenle @Jay (yöntemleri tanıtarak, örneğin göre) soyutlamalar açık hale olmasıdır olduğu kuralı. Bunu yapmamak, çünkü bir satırı olan bir yönteme sahip olabilirsiniz. Beni tefsir edelim gerçek ", soyutlamalar tanıtmak programlama dilinin yapı (tipik yöntem ve sınıfları) kullanın: keyfi kural olmadıkça o soyutlama uygulanması bir satır kod olarak ifade edilebilir, bu durumda içinde soyutlama belirtmek doğal dil ekleyerek bir yorum."
Eric

3

Bazı dillerde (örneğin F #) bu yorum / dokümantasyonun tamamı yöntem imzasında ifade edilebilir. Bunun nedeni F # 'da null' ın özellikle izin verilmediği sürece genellikle izin verilen bir değer olmamasıdır.

Ne (aynı zamanda ve diğer bazı fonksiyonel diller) F # yaygındır yerine null bir seçenek türü kullanmasıdır Option<T>olabilir ya Noneya Some(T). Dil bunu daha sonra anlar ve kullanmaya çalıştığınızda her iki durumda da eşleşmeniz (veya sizi uyarmazsanız sizi uyarması) için zorlardı.

Mesela F # 'da buna benzeyen bir imzanız olabilir

val GetProductById: int -> Option<Product>

Ve sonra bu, bir parametre (bir int) alan ve daha sonra bir ürün ya da Yok değerini döndüren bir işlev olacaktır.

Ve sonra bu şekilde kullanabilirsin

let product = GetProduct 42
match product with
| None -> printfn "No product found!"
| Some p -> DoThingWithProduct p

Her iki olası durumla da uyuşmazsanız, derleyici uyarıları alırsınız. Dolayısıyla, orada boş referans istisnaları elde etmenin mümkün bir yolu yoktur (tabii ki derleyici uyarılarını dikkate almazsanız) ve ihtiyacınız olan her şeyi sadece fonksiyon imzasına bakarak bilirsiniz.

Tabii ki bu, dilinizin bu şekilde tasarlanmasını gerektirir - C #, Java, C ++ gibi birçok ortak dil değildir. Öyleyse bu, şu andaki durumunuz için size yardımcı olmayabilir. Ancak (umarım) bu tür bilgileri yorumlara başvurmadan vb. Statik olarak yazılmış bir şekilde ifade etmenizi sağlayan diller olduğunu bilmek güzel. :)


1

Burada bazı mükemmel cevaplar var ve söylediklerini tekrarlamak istemiyorum. Ama birkaç yorum ekleyeyim. (Amaçlanan herhangi bir punto.)

Akıllı insanların yaptıkları - yazılım geliştirme ve diğer birçok konu hakkında, sanırım - bağlam içinde anlaşıldıklarında çok iyi tavsiyelerde bulunan, ancak bağlam dışına çıktıklarından veya uygunsuz durumlarda uyguladıklarından veya bunlara başvurduklarından daha aptal olan birçok ifade var. gülünç aşırılıklar.

Kodun kendi kendini belgelemesi gerektiği düşüncesi böyle mükemmel bir fikirdir. Ancak gerçek hayatta, bu fikrin pratikliği konusunda sınırlamalar vardır.

Birincisi, dilin net ve kesin olarak belgelenmesi gerekenleri belgelemek için özellikler sağlamayabilmesidir. Bilgisayar dilleri geliştikçe, bu sorun daha az ve daha az olur. Fakat tamamen ortadan kalktığını sanmıyorum. Meclis'te yazdığım günlerde, "toplam fiyat = vergilendirilemez öğelerin fiyatı artı vergilendirilebilir öğelerin fiyatı ve vergilendirilebilir öğelerin fiyatı * vergi oranı" gibi bir yorum eklemek çok mantıklı geldi. Tam olarak herhangi bir anda bir sicil kaydında ne olduğu belli değildi. Basit bir işlem yapmak için birçok adım attı. Vb Ama eğer modern bir dilde yazıyorsanız, böyle bir yorum sadece bir kod satırının yeniden ifadesi olur.

"X = x + 7; // x'e 7 ekle" gibi yorumlar gördüğümde her zaman sinirleniyorum. Mesela vay, teşekkürler, artı işaretinin ne kadar yardımcı olabileceğini unutmuş olsaydım. Gerçekten kafamın karışabileceği yer, “x” in ne olduğunu ya da neden belirli bir zamanda ona 7 eklemenin gerekli olduğunu bilmektir. Bu kod, "x" e daha anlamlı bir ad vererek ve 7 yerine sembolik bir sabit kullanarak kendi kendini belgeleyebilir. "Total_price = total_price + MEMBERSHIP_FEE;" yazmış olsanız bile, muhtemelen hiç bir yoruma ihtiyaç duyulmaz. .

Bir fonksiyon adının size bir fonksiyonun tam olarak ne yaptığını söylemesi gerektiğini söylemek güzel bir şey, böylece herhangi bir ek yorum gereksiz olabilir. Bir öğe numarasının veri tabanımızdaki Öğe Tablosunda olup olmadığını kontrol eden, doğru veya yanlış döndüren ve "ValidateItemNumber" olarak adlandırdığım bir işlev yazdığımı hatırlatan anılarım var. İyi bir isim gibi görünüyordu. Sonra bir başkası geldi ve bu işlevi, öğe için bir sipariş oluşturmak ve veritabanını güncellemek için değiştirdi, ancak adı hiçbir zaman değiştirmedi. Şimdi adı çok yanıltıcı oldu. Gerçekten çok daha fazlasını yaptığında küçük bir şey yapmış gibiydi. Daha sonra birisi ürün numarasının doğrulanması ile ilgili bir rol bile üstlendi ve başka bir yerde yaptı, ancak yine de adını değiştirmedi. Böylece, işlevin şimdi öğe numaralarını doğrulamakla bir ilgisi olmasa da,

Ancak pratikte, bir işlev adının, işlev adı, işlevi oluşturan kod olmadığı sürece, işlevin ne yaptığını tamamen tanımlaması genellikle imkansızdır. Bu ad bize tüm parametrelerde tam olarak hangi doğrulamaların yapıldığını söyleyecek mi? İstisna koşullarında ne olur? Her olası belirsizliği heceleyerek mi? Bir noktada, isim o kadar uzun sürecekti ki, sadece kafa karıştırıcı hale geliyor. Dize BuildFullName (Dize adı, Dize soyadı) düzgün bir işlev imzası olarak kabul ediyorum. Bu adın "ilk son" veya "son, ilk" veya başka bir varyasyonun ifade edilip edilmediğini, ismin bir kısmı veya her ikisi de boşsa, birleştirilmiş uzunluk sınırlar koyarsa ne yapabileceğini ve aşılırsa ne yapar

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.