tolgacelik.net
Tüm yazılar
·4 dk

Legacy Kod ile Çalışmak: Yeniden Yazma Tuzağına Düşmemek

Her senior engineer kariyerinde defalarca legacy kodla yüzleşir. "Yeniden yazalım" cazip ama tehlikeli. Strangler fig, test-before-refactor, küçük adımlarla evrim — yıllarca deneyimden ders.

legacy-coderefactormimarievolution

Yeni bir işe başlıyorsun. İlk gün code base'i açıyorsun. 2014'ten kalma kod, 6 farklı dev'in dokunduğu, hiç dokümante edilmemiş, test'i yok ya da kırık. İlk içgüdün: "Bunu yeniden yazalım."

Bu içgüdüye direnmen gerekiyor. Yeniden yazma, yazılım mühendisliğinin en kötü kararıdır — büyük çoğunluk durumda. Bu yazıda alternatifleri ve gerçekten kullanılabilir pratikleri.

Yeniden yazma neden tuzak

Joel Spolsky'nin meşhur cümlesi: "Bir şirketin yapabileceği en kötü stratejik hata, kodu sıfırdan yeniden yazmaktır."

Sebepler:

1. Eski kod görünmez bilgi içerir. O kod yıllar boyunca yamandı. Her yama bir bug fix'i, bir edge case'i, bir müşteri rica'sını taşıyor. Yeniden yazarken bu bilgi kaybedilir. Yeni kod 6 ay sonra aynı bug'ları üretmeye başlar.

2. "Yeni kod yazmak eski kod okumaktan kolay." Bu yanılgı. Yeniden yazma 2 ay tahmin edilir, 12 ay sürer. İlk 6 ay yeni kodda tam fonksiyonalite olmaz, paralel iki sistem yönetilir, iki katı iş çıkar.

3. Yeniden yazma sırasında ürün durur. Ekibin %80'i yeni sisteme yatırılır, eski sistemde sadece bug fix yapılır. Müşteri yeni özellik göremez. Rakipler ileri gider.

4. Bittiğinde "modern" hisseder ama aynı sorunları içerir. Yeniden yazma "modernleşmek" olarak satılır ama mimarideki aynı yanlışlar yeniden inşa edilir, çünkü ekip onları tanımlamadan yazmıştır.

Strangler fig pattern

Yeniden yazma yerine kademeli evrim. Adı Martin Fowler'ın strangler fig pattern.

Konsept: eski sistem etrafında yeni sistem inşa eder. Yeni sistem yavaş yavaş eski sistemin işlerini devralır. Eski sistem yavaşça gereksizleşir. Hiç "büyük yeniden yazma" anı yoktur.

Pratik adımlar:

1. Bir gateway / proxy katmanı koy. Tüm istekleri bir entry point'ten geçir. Önce eski sisteme yönlendirir.

2. Bir özelliği yeni kodla yeniden yaz. Tek bir endpoint, tek bir akış. Gateway'i o özelliği yeni kod'a yönlendirecek şekilde yapılandır. Eski kod o özellikte hâlâ var ama trafik gelmiyor.

3. Test, doğrula, deploy. Yeni özellik canlıda. Eski kod hâlâ orada (güvenlik için) ama kullanılmıyor.

4. Eski kodu sil. Trafik 0 olduğu doğrulandıktan sonra eski kod silinir.

5. Bir sonraki özelliği seç, başa dön.

Bu yaklaşım 6 ay - 2 yıl sürer ama:

  • Hiç "down day" olmaz
  • Her adımda paranız size geri döner (yeni özellik canlıda)
  • Hata olursa adım geri alınır
  • Ekip yeni sisteme alışırken eskisi de çalışıyor

Test-before-refactor

Eğer bir kod bloğunu rahatça refactor etmek istiyorsan, önce test yaz. Davranışı kapsayan test'ler.

1. Mevcut kodun davranışını kapsayan test'ler yaz (test'ler eski kodda geçiyor)
2. Refactor yap
3. Test'ler hâlâ geçiyor mu? Geçiyorsa refactor güvenli

Test yoksa refactor = umuda dayalı kod değişikliği. Bu yolla yıllarca legacy kod evrim'i mümkün.

Boy Scout Rule

Robert C. Martin'in basit kuralı: "Daire'yi bulduğun halden biraz daha temiz bırak."

Yeni özellik yazıyorsun, dokunduğun dosyada eski bir kod var. Refactor sırasıdir. Ama hassasiyetle:

  • Sadece dokunduğun yer. Tüm dosyayı yeniden yazma.
  • Test ile. Her değişiklik test'le doğrulanmalı.
  • PR scope'unu büyütme. "Refactor + new feature" PR'ı = review zor, riskli. Refactor önce, sonra feature.

Bu disiplin 6 ay - 1 yıl içinde dramatic fark yapar. Kod bir nesil sonra çok daha temiz olur — hiç "yeniden yazalım" demeden.

Theseus'un gemisi problemi

Bir geminin tüm parçaları zamanla değiştirilse, hâlâ aynı gemi mi? Felsefi soru, ama yazılımda pratik etkisi var.

Strangler fig + Boy Scout uygulanan bir kod tabanı, 2 yıl sonra bambaşka olur. Eski versiyondan tek bir satır kalmamış olabilir. Ama "yeniden yazma" yok — her gün küçük adımlarla evrim.

Bu, yeniden yazma'nın istemediğin tüm sonuçlarını veren ve istediğin tüm sonuçlarını veren yaklaşım.

Hangi durumda gerçekten yeniden yazma

Az ama gerçek senaryo:

  • Sistem ölmek üzere: kullanılan dil/framework support'u bitti, security patches almıyor, hâlâ çalışıyor ama 6 ay içinde patlama riski. Bu durumda evrim yetmez, paralel inşa gerek.

  • Bambaşka bir mimariye gerek var: monolith'ten distributed'a (örn. cloud-native dönüşüm). Strangler fig kullanılır ama paralel inşa kaçınılmazdır.

  • Çok küçük sistem: 1000 satırlık bir araç. Yeniden yazmak 1 hafta. Test etmek aynı süre. Risk düşük. Burada yeniden yazma uygundur.

Bunlar dışında: evrim et.

İnsan tarafı

Legacy kod yıllar süren işin sonucudur. O kodu yazan kişiler hâlâ ekipte olabilir, gurur kaynakları olabilir. "Bu kod berbat" demek profesyonel bir tonla yapılmalı:

  • "Bu kod 6 yıl önce farklı koşullarda yazılmış" (suçlamak yerine bağlam)
  • "Mevcut ihtiyaçlarımıza adapte etmek istiyoruz" (yıkmak değil dönüştürmek)
  • "Eski kararlardan öğrendiğimiz var, ona dayanıyoruz" (saygı)

Bu ton kültürel olarak kritik. Aynı ekiplerle 5 yıl çalışmak istiyorsan, kimseyi public-shaming yapmadan eski kodla başa çıkmayı öğrenmen lazım.

Sonuç

Legacy kod sektörün gizli normu. Yeni iş başladığın gün karşılaşacaksın, 5 yıl sonra hâlâ orada olacak (ama dönüşmüş halde).

"Yeniden yazalım" demeden önce: strangler fig pattern + test-before-refactor + Boy Scout rule. Bu üçünü 1 yıl uygulayan ekip, eski kodu rahat çevreliyor olur.

Yeniden yazma, son çare. Önce evrim. Çoğu zaman evrim yeter — ve evrim, yeniden yazmadan ucuzdur.

PaylaşLinkedInX
Bir sonraki yazı doğrudan kutuna düşsün

Distributed sistemler, üretim stabilitesi, AI destekli geliştirme üzerine uzun yazılar. Spam yok, çıkmak kolay.

Sadece e-posta. Bu sunucuda saklanır. Hiçbir yerde paylaşılmaz, satılmaz.

Yorumlar

Henüz yorum yok. İlk yorumu sen bırak.

Yorum bırak

Hiçbir yerde gösterilmez. Sadece gerekirse cevap vermek için.