52 puan yazan GN⁺ 2025-02-06 | 6 yorum | WhatsApp'ta paylaş
  • Deneyimli geliştiricilerin yeni geliştiricilerle yazılım geliştirme felsefesini paylaştığı içerik
  • Baştan yazımdan (ground-up rewrite) kaçınma, takvim yönetimi, kod kalitesi, otomasyon, edge case’lere hazırlık gibi çeşitli konularda tavsiyeler içeriyor

Ne pahasına olursa olsun, baştan yazımın (ground-up rewrite) cazip göründüğü durumlardan kaçının

  • Baştan yazımın cazip gelmeye başladığı an, birikmiş teknik borç nedeniyle mevcut kodu sürdürmenin zaten zorlaştığı andır
  • Kod karmaşıklığı birikmeye başladığında, uyarı işaretlerini erkenden fark edip (basit değişikliklerin bile zorlaşması, yorum/dokümantasyon yazmanın güçleşmesi, çekirdek kodu anlayan kişi sayısının azalması vb.) aktif olarak çözüm aramak gerekir
  • Genişleme işi bittikten sonra mutlaka karmaşıklığı azaltan ve kaliteyi toparlayan bir entegrasyon aşamasından geçilmelidir
  • Baştan yazım kaçınılmaz hale geldiyse, bu proje zaten tehlikeli bir aşamaya girmiş demektir
  • Riski azaltmak için teknik borcu sürekli yönetmek ve kod kalitesini dikkatle izlemek gerekir

Mümkün olan sürenin yarısında toplam işin %90’ını tamamlamayı hedefleyin

  • Kodu ilk aşamada yazıp çalışır hale getirmek, toplam işin yaklaşık yarısıdır
  • Sonraki aşamaları düzgün bitirmek için (edge case’lerin ele alınması, test, dağıtım, dokümantasyon, performans, bakım kolaylığı vb.) düşünüldüğünden çok daha fazla zaman gerekir
  • Yeterli tampon süre bırakıp beklenmedik sorunlara ya da son rötuş işlerine hazırlıklı olmak gerekir
  • Sonuçta, “ilk kodu kabaca çalışır hale getirmek” ile “tamamlanmış bir özellik haline getirmek” arasındaki farkı kabul edip bunu takvime yansıtmak gerekir

İyi uygulamaları otomatikleştirin

  • Geliştiricilere tekrar tekrar sözlü ya da yazılı olarak “böyle yapmalısınız” demek, hatalara açık bir yöntemdir
  • Mümkün olduğunda, otomatik testler veya script’lerle bunu “kural ihlal edilirse build başarısız olur” şeklinde zorunlu kılmak daha etkilidir
  • Yeni getirilen kurallar için de (yasaklanacak API’ler, mutlaka eklenmesi gereken yorumlar vb.) kademeli otomasyon uygulanarak hata ve atlamalar azaltılabilir
  • Ancak her şeyi otomatikleştirmek mümkün değildir; aşırı katı kurallar geliştirme akışını engelleyebileceği için denge gerekir

Uç (patolojik/Pathological) verileri de hesaba katın

  • Kodu yalnızca normal girdilerle (golden path) değerlendirmek risklidir
  • İsteklerin geciktiği ya da yarıda kesildiği durumlar, çok büyük veri kümeleri (milyonlarca ila yüz milyonlarca satır), garip string’ler (aşırı uzun olanlar, slash veya boşluk içerenler) gibi problemli senaryolar varsayılmalıdır
  • Edge case’lere kapsamlı şekilde hazırlanmak, nihai kod kalitesini belirler

Genelde daha basit yazılabilecek bir yol vardır

  • Başta kodu çalışır hale getirdikten sonra, zaman ayırıp dönerek onu daha basit ve daha açık hale getirmek iyidir
  • “İyi görünen bir çözüm” bulsanız bile, daha iyi bir çözüm olup olmadığını yeniden gözden geçirecek alan bırakmak önemlidir
  • Uzun ve karmaşık kodu daha özlü hale refactor etmek, nihai kaliteyi yükseltir

Kodu test edilebilir şekilde yazın

  • Arayüzleri ve side effect’leri en aza indirmek, otomatik test yazmayı çok daha kolaylaştırır
  • Yapı test etmesi zorsa, encapsulation muhtemelen doğru kurulmamıştır
  • Kod yapısını testlerin iyi işleyeceği şekilde tasarlamak, hataları erken yakalamayı sağlar

Kodun “kanıt üzerinde” sorunsuz olması işin bittiği anlamına gelmez

  • Yapısal olarak güvenli görünen kodda bile, çevre koşulları ya da bazı çağrı biçimleri değişirse sorun çıkabilir
  • Güvenlikle ilgili kodlarda, mevcut çağrı noktaları güvenli olsa bile gelecekte değişebileceği düşünülerek tasarım yapılmalıdır
  • Kod, “apaçık güvenli ve değişse bile sorun çıkarmayacak” biçimde yazılmalıdır

Yorumlar

  • “Bu mektubu kısa yazamamamın nedeni, onu kısa yazacak zamanımın olmamasıydı” sözünün kaynağı Pascal’dır
  • Her zaman off-by-one error’a dikkat edin
  • Wiki’ye yeni yönergeler eklemek
    • Şirket içindeki dokümantasyon/bilgi paylaşım sistemi düzgün kurulmamışsa, bilgi dağılır ve kafa karıştırıcı bir durum ortaya çıkar
    • Resmî belgeler onay sürecinden geçerken eski sürüme dönüşebilir ya da birden fazla wiki aynı anda var olup hangisinin resmî kaynak olduğu belirsizleşebilir
    • Tüm materyalleri tek bir wiki’de toplamak ve eksik yerleri geliştiricilerin doğrudan yazarak ya da reverse-engineering ile tamamlaması etkili bir yöntemdir
    • Dokümantasyon başka yerlere (source control, kod yorumları vb.) iyi bağlanmışsa güncel tutmak daha kolay olur
    • Otomatik testler ve build ortamı karmaşıksa veya geliştiricilere görünür değilse, herkesin tüm testleri gerçekten hiç çalıştırmadığı bir durum oluşabilir
    • Jenkins build script’lerini basit tutup cd project; ./build-it biçiminde düzenlemek ve script’in kendisini de source control’e dahil etmek avantajlıdır
    • Tüm ekibin aynı ortamda (ör. sanal makine imajı, build ayarları) build ve test çalıştırabilmesini sağlamak, sorunları önceden azaltabilir
    • Edge case’leri geliştirme aşamasında düşünerek destroy_object(foo) çağrısının foo NULL olsa bile güvenli çalışmasını sağlamak ya da create_object() başarısız olursa içeride destroy_object() çağırmak faydalıdır
    • Sonuç olarak, tüm geliştiricilerin dokümantasyona ve build/test ortamına kolayca erişip katkı verebilmesi önemlidir
  • Dokümantasyon ve otomatik testler: Bilgi paylaşımı için belge veya wiki’nin önemi ve Jenkins gibi CI/CD ortamlarının ayarlarının paylaşılabilir olması gerektiğine dair pratik bir öneri de geçiyor
  • İnsanlara istenen davranışı ezberleyene kadar “rahatsızlık vermekten” daha etkili bir davranış değişikliği aracı yoktur
  • Satrançta bir özdeyiş olan “İyi görünen bir hamle görürsen, hemen yap” sözünde olduğu gibi, programlamada da buna karşı bir görüş vardır. İşin iki yüzü bulunur.

6 yorum

 
bbulbum 2025-02-07

> Genellikle daha basit yazılabilecek bir yöntem vardır

Daha öz bir çözümü düşünmenin, kod ve politika karmaşıklığını azalttığına inanıyorum.

 
kipsong133 2025-02-06

> "Mümkün olan sürenin yarısında tüm işin %90'ını tamamlamak"

Bu söz gerçekten çok doğru gibi geliyor. Her şeyi tek seferde kusursuz uygulamaya çalışmaktansa, hızlıca ikinci turu görmek hem hataları azaltıyor hem de zaman yönetimini daha iyi yapmayı sağlıyor.

 
jhj0517 2025-02-06
  1. İyi örnekleri otomatikleştirin (test kodu CI/CD pipeline'ı)
  2. Önce kodu çalışır hale getirmek, ardından zaman tanıyıp dönerek onu daha basit ve daha anlaşılır olacak şekilde iyileştirmek daha iyidir
  3. Baştan sona yeniden yazımın (ground-up rewrite) cazip göründüğü durumlardan ne olursa olsun kaçının
 
winterjung 2025-02-06

> Her zaman off-by-one error'a dikkat edin

Off-by-one error'ın ne olduğunu merak etmiştim; meğer for (int i = 1; i < n; ++i) { ... }, for (int i = 0; i <= n; ++i) { ... } gibi sınır koşullarıyla ilgili bir hata türüymüş.

 
ethanhur 2025-02-06

> Bedeli ne olursa olsun, sıfırdan yeniden yazımın (ground-up rewrite) cazip göründüğü durumlardan kaçının

Bence bu, birçok BT şirketinin işinin gelişmesini engelleyen bir pitfall gibi görünüyor ve teknik borcun çok biriktiği durumlarda bunu gideremeyen (veya gidermek istemeyen) mühendislik organizasyonları, sıfırdan yeniden yazımı cazip buluyor gibi görünüyor.

Yazarların, gerçekten ikna edici bir gerekçe yoksa yeniden yazımdan mümkün olduğunca kaçınılması gerektiği yönündeki görüşüne içtenlikle katılıyorum.

 
GN⁺ 2025-02-06
Hacker News görüşü
  • Yazılım geliştirme, deneme ve öğrenmenin tekrar eden bir sürecidir. Deneyimli geliştiriciler, kod yazarak ve test ederek anlayışlarını derinleştirir ve çok şey öğrenir, ancak bu durum toplantılarda ya da planlamada pek görünmez. Junior geliştiriciler, production'a hazır kod sunmakta zorlanır ve çöpe gidecek iş üretmekten kaçınır. Yöneticinin geliştirme deneyimi azsa bu sorunlar daha da kötüleşebilir

  • "Uzun bir mektup yazdığım için özür dilerim, ama kısa yazacak vaktim yoktu" alıntısı, Fransız matematikçi ve filozof Blaise Pascal'a aittir ve kısa yazmanın daha zor olduğu anlamını taşır

  • 90/50 kuralı, kod kalitesini artırmak için testlere ve exception handling'e önem verilmesi gerektiğini vurgular. Otomatik test kurmak, codebase içinde net beklentiler belirlemeye yardımcı olur

  • Bilgisayar bilimi eğitimi çoğu zaman insanları karmaşık kod yazmaya yönlendirir, ancak okunması kolay kod yazmak önemlidir. Değişken ve fonksiyon adlandırması, tutarlı formatting ve modüler tasarım gereklidir

  • Ratchet adlı mekanizma, gelecek için kusursuz bir yöntem sunar

  • Deneyimi ve alan farkındalığını genelleştirme çabası, hatalı genellemelere yol açabilir. Geliştirme, karmaşıklığı yönetme sanatıdır ve başarısızlıklardan öğrenmek önemlidir

  • "İşin ilk %90'ı zamanın %90'ını alır, kalan %10 da bir %90 daha alır" alıntısı, geliştirmenin gerçekliğini iyi yansıtır. Exception handling, hatalar, kullanılabilirlik ve güvenlik gibi konular hesaba katıldığında beklenmedik biçimde çok fazla iş gerekir

  • Joel Spolsky'nin yazısı, yeniden yazmanın riskleri konusunda uyarır ve DevOps bilgeliğini vurgular

  • Kodun okunabilirliğini optimize etmek ve bir bug bulunana kadar geçen süre uzadıkça maliyetin arttığını kabul etmek gerekir. Functional programming ilkelerini tercih etmek ve güçlü type system kullanmak faydalıdır