Bir code review’da şu yorumla sık karşılaşıyorum: // ileride başka sağlayıcı da gelebilir. Hemen altında tek implementasyonlu bir interface, onu yaratan bir factory ve hiç okunmayan bir config anahtarı durur. Planlanan ikinci sağlayıcı yoktur — sadece ihtimali vardır.

Bu kod bedava yazıldı sanılır. Değil. “İleride lazım olur” diye eklenen her esneklik, kullanılmaya başlanana kadar her gün faiz ödeyen bir borçtur.

Spekülatif genellik nedir

Spekülatif genellik, bugün var olmayan bir gereksinim için bugünden esneklik inşa etmektir. Tek satıra yetecek yere bir strateji deseni, tek tipe yetecek yere generic bir parametre, tek çağrı için bir event sistemi.

Gerekçe hep aynı kelimelerle gelir: “ileride”, “ne olur ne olmaz”, “genişletilebilir olsun”. Hepsi geleceğe dair bir tahmindir. Ve tahmin, bir kod tabanının en pahalı parçasıdır.

Faturanın kalemleri

Kullanılmayan esneklik boş durmaz; her gün şu kalemleri öder:

  • Okuma maliyeti. Kodu okuyan herkes “bunun ikinci bir kullanımı var mı” diye arar, bulamaz, kafası karışmış hâlde devam eder. Esneklik, var olmayan bir senaryoyu sürekli düşündürür.
  • Bakım maliyeti. Soyutlama, altındaki gerçek koda her dokunuşta birlikte güncellenir. Boş bir katman bile bakım ister.
  • Hata yüzeyi. Çalışmayan kod, çalışan kodu kırabilir — yanlış dallanma, ölü bir branch’te unutulmuş bir bug, hiç test edilmemiş bir yol.
  • Yanlış soyutlamaya kilitlenme. En pahalısı bu. Bugün tahminle çizdiğiniz interface, yarın gerçek ihtiyaç geldiğinde neredeyse hiç uymaz — ama artık onu söküp atmak, baştan yazmaktan zordur.
  • Test yükü. Her fazladan dolaylılık, test kurulumunu uzatır; mock sayısını artırır.

Boring architecture yazısındaki “karmaşıklık bütçesi” burada da geçerli: spekülatif genellik o bütçeyi, hiçbir şey teslim etmeden harcar.

Tahmin neredeyse hep yanlış çıkar

“İleride lazım olur” kodunun en acı yanı şu: ileride gerçekten bir şey lazım olduğunda, lazım olan şey tahmin ettiğiniz şey değildir.

İkinci ödeme sağlayıcısı sonunda gelir — ama sizin interface’inizin hiç varsaymadığı bir async webhook akışıyla gelir. İkinci kiracı (tenant) gelir — ama satır bazlı izolasyonla değil, ayrı şema ile. Önceden çizilmiş esneklik, gerçek gereksinimle karşılaşınca bir yardım değil, bir engel olur: önce onu kaldırmanız gerekir.

Domain’i en az tanıdığınız an, projenin ilk haftasıdır; geleceğe dair en kötü tahminleri tam da o an verirsiniz. Modüler monolit yazısında sınırların ilk haftada neredeyse kesin yanlış çizileceğini söylemiştim — aynı şey her erken soyutlama için geçerlidir.

YAGNI’yi pratikte uygulamak

“You Aren’t Gonna Need It” bir tembellik izni değil, bir zamanlama kuralıdır: esnekliği, ihtiyaç kanıtlandığında ekle — tahmin edildiğinde değil.

Pratik karşılığı:

  • Bugünün bilinen vakası için yaz. Tek sağlayıcı varsa tek sağlayıcıyı yaz. Düz, doğrudan, okunur.
  • Üç kuralı. Bir kalıbı soyutlamadan önce üç gerçek kullanımını bekle. İki, tesadüf olabilir; üç, bir desendir.
  • Dikişi sonra aç. İkinci sağlayıcı gerçekten geldiğinde interface’i çıkarmak bir IDE refactor’ı — birkaç saat. O birkaç saati bugünden ödemenin hiçbir getirisi yok.

Asimetri şurada: düz kodu sonradan soyutlamak kolaydır. Yanlış soyutlamayı sonradan düzleştirmek zordur. Bu asimetri YAGNI’den yanadır.

Ne zaman önden esneklik haklı?

Her şeyi son ana bırakmak da değil. Ayrım, kararın geri dönülebilir olup olmadığında:

  • Geri dönülebilir kararlar (çift yönlü kapı). Bir sınıfın iç yapısı, bir fonksiyonun imzası, kod organizasyonu. Bunları sonradan değiştirmek ucuz — bugünden esnek tutmaya gerek yok.
  • Geri dönülmesi zor kararlar (tek yönlü kapı). Veritabanı şeması, dışarıya verilmiş bir API kontratı, veri formatı, güvenlik sınırı. Bunlarda ileriyi düşünmek spekülasyon değil, sorumluluktur — çünkü hatanın bedeli production’da veri göçü demektir.

Kural şu: kodun içinde cömertçe basit ol; dışa açtığın ve veriye yazdığın yerde tedbirli ol. Esnekliği, geri almanın gerçekten pahalı olduğu yere sakla.


“İleride lazım olur” cümlesi bir gereksinimi değil, bir korkuyu ifade eder. Kodu korkuyla değil, kanıtla büyütün.

En kolay silinen kod, hiç yazılmamış olandır.