Büyük bir kod temeli nasıl daha kolay anlaşılır


104

Diyelim ki nispeten büyük bir proje geliştiriyorum. Tüm sınıflarımı ve işlevlerimi Doxygen ile zaten belgeledim, ancak her kaynak kod dosyasına bir "programcı notu" koymak için bir fikrim vardı.

Bunun arkasındaki fikir, meslekten olmayan bir terimle belirli bir sınıfın nasıl çalıştığını açıklamaktır (sadece çoğu yorumda neden olduğu gibi değil ). Başka bir deyişle, diğer programcılara bir sınıfın nasıl çalıştığı hakkında başka bir görüş vermek.

Örneğin:

/*
 * PROGRAMMER'S NOTES:
 *
 * As stated in the documentation, the GamepadManager class 
 * reads joystick joystick input using SDL and 'parses' SDL events to
 * Qt signals.
 *
 * Most of the code here is about goofing around the joystick mappings.
 * We want to avoid having different joystick behaviours between
 * operating systems to have a more integrated user experience, since
 * we don't want team members to have a bad surprise while
 * driving their robots with different laptops.
 *
 * Unfortunately, we cannot use SDL's GamepadAPI because the robots
 * are interested in getting the button/axes numbers, not the "A" or
 * "X" button.
 *
 * To get around this issue, we created a INI file for the most common 
 * controllers that maps each joystick button/axis to the "standard" 
 * buttons and axes used by most teams. 
 *
 * We choose to use INI files because we can safely use QSettings
 * to read its values and we don't have to worry about having to use
 * third-party tools to read other formats.
 */

Bu, yeni programcıların / katılımcıların nasıl çalıştığını anlamalarında büyük bir projeyi kolaylaştırmak için iyi bir yol olabilir mi? Tutarlı bir kodlama stili ve 'standart' rehber organizasyonu sürdürmenin yanı sıra, bu durumlar için herhangi bir 'standart' veya önerileri var mı?


32
Cehennem hayır. Kodunuz okunamıyorsa, belgeler yardımcı olmaz.
Telastyn

35
@jeffo - sorun şu ki, bunun için zaman ayırmanın bir kez olabileceği yönünde. Kodu okunaklı tutma süresi zamanla olur. Proje gençken veya Mükemmeliyetçi Joe hala takımdayken yapılan bu tür belgelerle bulundum. Daha sonra terk edildi ve yorumlar devam etti, artık doğru değil.
Telastyn

25
En azından daha yüksek bir seviyede, bir projenin ne yaptığını, nasıl çalıştığını ve mimaride hangi tradeolyonların yapıldığını paha biçilmez kılan bir kod dışı açıklama. Bu tür bir belge, kod turuna çıkmadan önce yeni başlayanlar için okunması gereken bir şeydir . Orada bir sürü net etrafında saçmalık my-metodolojisi-de-radikal-için-docs-ahbap olduğunu ve süre olduğu olduğu bir ilk kemer doc ve gelişmekte olan kemer doc hizada olmaz doğrudur, bir düzyazı açıklama gereklidir Herkes için büyük, önemsiz olmayan bir kod tabanını hızla kavraması. İşte (zayıf) bir örnek: zxq9.com/erlmud/html/001-002_architecture.html
zxq9 08:51 de

11
@Telastyn: Bunun kodun okunup okunamayacağı ile ilgisi yok (ve umarım öyledir). Tasarım gerekçesini belgelemek kesinlikle önemlidir.
Orbit'teki Hafiflik Yarışları

7
@Telastyn: Evet, belki. Şahsen ben tek başına bir doktora yazarım. Ancak kaynak dosyaların tepesindeki yorum blokları o kadar da kötü değil.
Orbit'teki Hafiflik Yarışları

Yanıtlar:


139

Bu harika. Keşke daha fazla yazılım geliştiricisi bunu yapmak için zaman ve çaba harcadı. O:

  • Sınıfın ne yaptığını İngilizce olarak belirtir (yani sorumluluktur),
  • Kodun zaten söylediği sözleri tekrar etmeden kod hakkında faydalı ek bilgiler sağlar,
  • Tasarım kararlarından bazılarını ve neden alındıklarını ana hatlarıyla belirtin ve
  • Kodunuzu okuyan bir sonraki kişinin düşebileceği bazı kazanımların altını çizer.

Ne yazık ki, birçok programcı "eğer kod doğru yazılırsa belgelenmesi gerekmiyor" kampına girer. Doğru değil. Kod sınıfları, yöntemler, modüller ve sadece kodun kendisini okumaktan açık olmayan diğer eserler arasında birçok zımni ilişki vardır.

Tecrübeli bir kodlayıcı, dokümantasyon olmadan açık, net, kolay anlaşılır bir mimariye sahip bir tasarımı dikkatlice hazırlayabilir. Fakat bunun gibi kaç tane program gördünüz?


15
Ve neden "Efsanevi Adam Ayı" kendi kendini gerçekleştiren bir kehanet haline geliyor, hiç kimse yeni aklı için bütün bunları aklından yeni çıkınca ve proje geride kalmayarak yazmaya zaman ayırmadı.
JeffO,

3
Burada yaptığın her noktaya katılıyorum. OP'nin görevinde kullanılan terimini sevmiyorum how a class works. Bu zaman ve bakımla değişir. Yine de ekibim yukarıdakileri kaynağa koymadı. Kararları içeren bir wiki tutarız ve tasarım kararları hakkındaki gevşek kanal tartışmasını bir belgeye aktarırız (Karar özetinden ve sonuçtan ham notlara bir bağlantı sağlarız, böylece eski kararları yeniden almak zorunda kalmayız). Hepsi titizlikle özenle yapılır (yani hepsi tek bir yerdedir).
Martin York

1
Tek sorunum bunu küresel olarak uygulamak. Bu sınıf yeterince karmaşıktır, bazı elde edilenler mevcuttur, açıkça faydalıdır (yine de Yorum Rot ile başa çıkmanıza rağmen). Bir sınıf daha açık olduğunda, yorum biraz gereksiz olabilir.
deworde,

1
“Tecrübeli bir kodlayıcı, dokümantasyonu olmayan açık, kolay anlaşılır bir mimariye sahip bir tasarımı dikkatlice tasarlayabilir. kod. İyi düzenlenmiş kod, anlamsızsa dokümantasyon için iyi olma eğilimindedir. Yoksul mimaride kod, "1 x artış" gibi yorumlar var
deworde

3
Bu cevaba kesinlikle katılıyorum ve OP'nin kodundaki örneği gibi bir şey bulursam çok mutlu olurum. Sadece tek bir ek: yorumunuza bir tarih eklemeyi düşünün , yalnızca nihai okuyuculara açıklamanın tazeliğine dair bir ipucu verin ve metni her güncellediğinizde güncelleyin.
Svalorzen

36

Büyük bir kod temeli ile çalışmanın anahtarı, değişiklik yapmak için tüm kod tabanını okumak zorunda değildir. Bir programcının aradığı kodu hızlıca bulmasını sağlamak için kodun düzenlenmesi ve kuruluşun görünür olması gerekir. Diğer bir deyişle, koddaki her bir mantıksal birim, çalıştırılabilir kitaplıktan, ad alanından bireysel sınıfa kadar açıkça görünür bir sorumluluğa sahip olmalıdır. Bu nedenle sadece kaynak dosyaları değil aynı zamanda içinde bulundukları dizinleri de belgelemek isterim.

Programcınızın notları aynı zamanda tasarım kararlarında da arka plan sağlar. Bu değerli bir bilgi olsa da, bunu sorumluluk bildirgesinden ayırırım (okuyucunun sınıfın sorumluluğu veya tasarım gerekçesi hakkında okumak isteyip istemediğini seçmesini sağlamak için) ve tanımladığı kaynağa yaklaştırmak olabildiğince, belgeler kodun kodunun güncellenmesi olasılığını en üst düzeye çıkarmak için (belgeler yalnızca doğruluğuna güvenebilirsek kullanışlıdır - eski belgeler hiç olmadığı kadar kötü olabilir!).

Bununla birlikte, belgeler DRY olarak kalmalı, yani kodda ifade edilebilecek veya başka bir yerde daha önce tanımlanmış olabilecek bilgileri tekrarlamamalıdır ("dokümantasyon durumları" gibi ifadeler bir uyarı işaretidir). Özellikle, gelecek koruyucular projenin programlama dilinde İngilizce olduğu gibi sadece bir uzmanlık kazanacaktır; yorumlarda uygulamanın daha iyi ifade edilmesi (insanlar dokümantasyonuyla gurur duydukları zaman çok sık görüyorum) faydası yoktur ve özellikle dokümantasyon tanımladığı koda yakın değilse uygulamadan sapma olasılığı yüksektir.

Son olarak, belgelerin yapısı proje genelinde standartlaştırılmalıdır, böylece herkes onu bulabilir (böcek izleyicisindeki Peter belgelerinin kraliyet karmaşası, wiki'deki Sue, beniokudaki Alan ve kaynak kodundaki John ...) .


İlk cümleniz aynen böyle görüyorum. Büyük kod tabanları, yeni bir programcının diğerlerini tehlikeye atmadan güvenli bir şekilde değiştirebileceği küçük bileşenlerden oluşmalıdır.
Jon Chesterfield

1
Kodlama sırasında belgelerin güncellenme olasılığını en üst düzeye çıkarmak için mümkün olduğunca açıklandığı kaynağa yakın bir yere getirin . Bu değerli bir deneyim.
laike9m

KURUTMA dokümantasyonu için bir rehber olarak çok iyi bir nokta! Bu otomatik olarak odağı otomatik olarak ayarlar ve meşhur iğrenç "// 1 x artış" yorumlarını yasaklar.
Hans-Peter Störr 10:15

13

Bunun çok iyi bir yaklaşım olduğu konusunda hemfikir değilim.

  1. Projenizi yeniden yansıtırken, yöntemleri hareket ettirin, belgeler bozulur.

  2. Dokümantasyon düzgün bir şekilde güncellenmezse, kodun anlaşılmasına yardımcı olmaktan çok karışıklığa neden olur.

Her bir modül için her bir yöntem / entegrasyon testi için birim testiniz varsa, kod açıklamalarına kıyasla daha bakımlı ve anlaşılması kolay bir öz dokümantasyon olacaktır.

Evet, uygun bir dizin yapısına sahip olmak kesinlikle yardımcı olacaktır.


Testler için +1, bir kod tabanını anlamanın en iyi yoludur. Ünite testleri, entegrasyon testleri, kabul testleri, uygulamanın nasıl çalışması gerektiği ve nasıl kullanılması gerektiği ile ilgili hikayeyi anlatır.
BZink

7

Şahsen, tasarıma genel bir bakış ve sınıfların ve kaynakların bir listesini veren - tercihen herhangi bir koddan ÖNCE yazılmış - bir üst düzey tasarım dokümanının hayranıyım. Yukarıdan aşağıya tasarım, işleri büyük ölçüde basitleştirir - sizin "oyun motoru -> donanım -> kontrolörleri -> joystick"; bu nedenle, yeni bir programcı "xyz kontrol cihazındaki" "bir" düğmeyi düzelt "en azından nereye bakacağını bileceğini söyledi.

Çok fazla sayıda modern dil, kodu yüzlerce küçük dosyaya bölme eğilimindedir, bu nedenle doğru dosyayı bulmak, ılımlı bir projede bile zor olabilir.


16
20 yıl önce tüm kodum büyük bir dosyadaydı. Şimdi binlerce küçük dosya ve test dosyasında. Bunun iyi bir nedeni var ve 20 yıllık yazılım geliştirmeyi yansıtıyor (genel ekosistem, bilgim değil). Waaay bir yorum için çok uzun olsa da.
Michael Durrant,

4
ah, eski bir şelale yazma yöntemi tek, tüm kapsayan, değişmez, kodlamadan önce gerçek, hatta başlar ve uygulamada bahsedilen gerçekten sapmayı imkansız kılar.
15’te

2
@jwenting: O kadar uzağa götürmek zorunda değilsin. Ama sahip olmak hala iyi bazı oluşturmakta ne fikir.
Robert Harvey,

1
Kesinlikle, bu kuralın uygun şekilde nasıl çözüleceğine ve kuralların nasıl çözüleceğine dair bir uyarı olmadan, çok hızlı bir şekilde güncel olmayan veya değirmentaşı olan bir belgeye sahip olacaksınız. “Yeni bir sınıf eklemeliyim; zaman alan Behemoth Documanto'ya!”
deworde,

2
@deworde: Bunu "dokümantasyonu sürdürmek için çok tembel" olarak okudum.
Robert Harvey,

6

Kod tabanı büyükse - tasarımının ve uygulamasının temel öğelerini belirleyen bir tasarım belgesi sunmaya çalışırım . Buradaki amaç kullanılan sınıfların hiçbirini ayrıntılandırmak değil, tasarıma ve düşünceye kodlama için bir anahtar sağlamaktır. Sisteme, bileşenlerine ve uygulamalarına kapsamlı bir bağlam verir.

Tasarım dökümanına dahil edilecekler;

  • Uygulama mimarisi
  • Mantıksal kod yapısı
  • Veri akışı
  • Kullanılan anahtar kalıplar ve kullanımlarının arkasındaki motivasyon
  • Kod kaynak yapısı
  • Nasıl inşa edilir (bu, örtük bağımlılıklar ve fiziksel kod kaynak yapısı hakkında fikir verir)

Bundan sonra , sınıflar için belgeler ve işlevler / yöntemler uygun şekilde tamamlanmalıdır . Özellikle halka açık API; Her durumda aşağıdakilerin ne olduğu açık olmalıdır;

  • Ön koşullar
  • Etkileri
  • Invariants
  • İstisna koşulları (atar)

+1 Her bir sınıfı tanımlamaktan daha iyidir, çünkü bu, genel bir tasarımdan çok daha eski bir tarihe geçecektir.
Lode

4

Yeni geliştiricilerin bir kod temeli anlamalarını kolaylaştırmak için bulduğum en önemli kural mükemmel anlaşmanın pahalı olmasıdır.

Yeni geliştiriciler üzerinde çalıştıkları sistemi mükemmel bir şekilde anlamalılarsa, iş öğrenmesi için tüm fırsatları önler. Programcının notlarının mükemmel bir başlangıç ​​olduğunu düşünüyorum ama daha ileri gideceğim. Yeniden yaklaşıldığında, bir geliştiricinin, onlardan önce öğrenmelerini istemek yerine, anında ne yaptıklarını bulmalarını sağlayacak bir kod yazmayı deneyin. Bildiğiniz davalar için iddialar gibi küçük şeyler asla ortaya çıkmaz, iddiaların neden geçerli olduğunu açıklayan yorumlar uzun bir yol kat eder. Eğer yanlış bir şey yaparsanız segfaulting yerine inceliksiz bir şekilde başarısız olan bir kod yazıyor.


Benim kuralım, yorumların NASIL değil, NEDEN hakkında olması gerektiğidir . Kod NASIL anlatılmaktadır.
user11393

3

Belgelere sahip büyük sınıflar gördüm ve belgeleri okuduktan sonra, bu sınıfın neyin iyi olduğu ve neden birinin kullanacağı hakkında hiçbir fikrim yok! Aynı zamanda, bazı işlevlere ihtiyacım vardı ve onu idare edecek bir sınıf olması gerektiğinden kesinlikle emin oldum ve hiçbir yerde bulamadım - çünkü beni sınıfa ihtiyaç duyduğumdan yönlendiren hiçbir belge yoktu. Bunu yapıyor.

Bu yüzden belgelerde isteyeceğim ilk şey, bir sınıfın ne yaptığı ve neden kullanmak istediğimle ilgili birkaç cümle. Asıl sorudaki yorumlar bu açıdan oldukça başarılı. Bu yorumları okuduktan sonra, çalışmadığı değerleri yorumlayamadığım için iyi çalışmayan bir joystickim varsa hangi kodu kontrol edeceğimi bilirdim.


0

@Meriton'ın söylediğine benzer şekilde, kodu ayrı bileşenlere bölün. Daha da iyisi, bileşenlerin nasıl ayrıldığını daha net hale getirmek için kod tabanını ayrı paketlere (JAR'lar, taşlar, yumurtalar, her neyse) ayırın. Bir hata varsa, bir geliştiricinin yalnızca hatanın bulunduğu paketi bulması ve (umarım) yalnızca orada düzeltmesi gerekir. Söylemeye gerek yok, birim testi yapmak daha kolay ve bağımlılık yönetiminden yararlanabilirsiniz.

Başka bir çözüm: kod tabanını küçültün. Ne kadar az kod varsa, o kadar kolay anlaşılır. Refactor kullanılmamış veya kopyalanmış kod. Bildirimsel programlama tekniklerini kullanın . Bu elbette çaba gerektirir ve çoğu zaman mümkün veya pratik değildir. Ama bu değerli bir hedef. Jeff Atwood'un yazdığı gibi: En İyi Kod Hiç Kod Yok


-1

Karmaşık sistemler için, sadece her bir dosyayı değil, etkileşimlerini ve hiyerarşisini ve programın nasıl ve neden oluştuğunu belgelemeye değer olabilir.

Örneğin, bir oyun motoru genellikle oldukça karmaşıktır ve yüzlerce soyutlamadan sonra neyin ne olacağına karar vermek zordur. Kodun nasıl ve neden böyle yapılandırıldığını ve neden bu anlamsız görünümlü soyutlama katmanının olduğunu açıklamak için "Architecture.txt" gibi bir dosya oluşturmaya değer olabilir.


-7

Bu kısmen olabilir çünkü tek bir programcının yazması zor, çünkü her birey yalnızca projenin bir bölümünü anlıyor.

Bazen bu bilgiyi proje yöneticisinin notlarından edinebilirsiniz, ancak elde edeceğiniz tek şey budur; çünkü notlarını bu formatta nadiren yeniden yazarlar.


7
Eğer github'a bakarsanız, bir README.md dosyasında bu tür bir notu olan birçok proje bulacaksınız. Genel olarak git kültürünün bir parçası haline geldi ve çoğu insan için javascript projeleri bu tür üst düzey dokümantasyonu olmayan bir kütüphaneyi kullanmayacak. Bu yüzden, "hiçbir programcı yazmaz" doğru değil çünkü yalnızca jQuery veya socket.io gibi bir şeye bakmanız ve böyle şeyler yazan programcıları bulmanız gerekiyor. Ayrıca, doğru olmayan README dosyalarının hata raporları oluşturduğu bir kültür haline gelmiştir.
Slebetman

1
Bu, önerilen dokümantasyon stilinin neden işe yarayıp yaramayacağına ve aynı zamanda dokümantasyon standartlarına neden olan sebepleri araştıran soruya cevap vermiyor gibi görünmektedir.
user52889

5
Bir ürün üzerinde çalışan bir programcı ekibiniz varsa ve her programcı yalnızca üzerinde çalıştıkları belirli kodu anlarsa, o zaman sadece takımınız saçma bir otobüs faktörü ile inanılmaz derecede işlevsel değildir, ancak biri kodun kalitesini sorgular. Kodun geri kalanını aynı sistemde anlayamadan kod bir ürüne nasıl entegre edilir ?!
Orbit'teki Hafiflik Yarışları
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.