Refactoring, kodun dışarıdan görünen davranışını değiştirmeden iç yapısını iyileştirmektir. Müşteri hiçbir fark görmez; ama bir sonraki özellik daha hızlı eklenir, bir sonraki hata daha kolay bulunur. Bir mutfağı yemek yaparken toplamak gibidir: yapmazsanız her yemek bir öncekinden daha zor hazırlanır.
Ne zaman refactoring yapılmalı?
- Yeni bir özellik eklemeden önce, kod bu özelliği kabul etmeye hazır değilse
- Bir hatayı düzeltirken, hatanın kaynağı karmaşık koddaysa
- Code review sırasında okunabilirlik sorunları fark edildiğinde
- Aynı değişikliği birden çok yerde yapmak zorunda kaldığınızda
"Refactoring sprinti" yerine sürekli ve küçük iyileştirmeler daha sürdürülebilirdir.
Kod kokuları (code smells)
Kod kokuları, mutlaka hata olmayan ama sorun habercisi olan işaretlerdir:
| Koku | Belirti | Olası çözüm |
|---|---|---|
| Uzun metot | Ekrana sığmayan fonksiyon | Metot çıkarma |
| Dev sınıf | Her şeyi yapan "Manager" | Sorumluluklara bölme |
| Tekrarlanan kod | Kopyala-yapıştır blokları | Ortak metot |
| Uzun parametre listesi | 6-7 parametreli metotlar | Parametre nesnesi |
| İlkel takıntısı | Her şey string ve int | Değer nesneleri (Para, Eposta) |
| Değişiklik yayılması | Bir değişiklik on dosyaya dokunuyor | Sorumlulukları toplama |
Güvenli refactoring adımları
- Testlerle güvenceye alın. Değiştireceğiniz davranışı koruyan testler yoksa önce onları yazın. Bkz. xUnit ile birim testi.
- Küçük adımlar atın. Her adımdan sonra kod derlenmeli ve testler geçmelidir.
- Geliştirme ortamının araçlarını kullanın. Yeniden adlandırma, metot çıkarma gibi otomatik refactoring komutları hata riskini azaltır.
- Refactoring ile yeni özelliği ayırın. Aynı commit'te hem davranış değişikliği hem yapı değişikliği yapmak incelemeyi zorlaştırır.
- Sık commit'leyin. Geri dönmek gerektiğinde küçük adımlar hayat kurtarır. Bkz. Git başlangıç rehberi.
Büyük yeniden yazım (rewrite) tuzağı
"Bu kod çok kötü, sıfırdan yazalım" kararı caziptir ama risklidir. Eski kod, yıllar içinde öğrenilmiş sayısız istisnayı ve iş kuralını sessizce içerir. Sıfırdan yazımda bunlar kaybolur, proje beklenenden uzun sürer ve iki sistemi aynı anda yaşatmak gerekir.
Daha güvenli yol, adım adım değiştirmektir: yeni modülleri yeni yapıyla yazmak, eski parçaları zamanla bunlarla değiştirmek. Bu yaklaşım, örneğin .NET Framework'ten modern .NET'e geçişte de en çok önerilen yöntemdir.
Yöneticiye nasıl anlatılır?
Refactoring'i "kodu güzelleştirmek" olarak değil, değişiklik maliyetini düşürmek olarak anlatın. "Bu modülü düzenlersek yeni kampanya kuralları bir hafta yerine iki günde eklenir" cümlesi, teknik terimlerden daha ikna edicidir. Konunun ekonomik boyutu için teknik borç yazısına bakabilirsiniz.
Sık sorulan sorular
Testi olmayan eski kodda refactoring yapılabilir mi?
Yapılabilir ama dikkatli olunmalıdır. Önce mevcut davranışı yakalayan basit "karakterizasyon testleri" yazmak riski büyük ölçüde azaltır.
Refactoring performansı düşürür mü?
Genellikle hayır. Okunabilir kodda performans sorunlarını bulmak ve çözmek daha kolaydır.
Sonuç
Refactoring, yazılımın yaşlanmasını yavaşlatan düzenli bakımdır. Küçük, test korumalı adımlarla yapıldığında risk taşımaz ve her yeni özelliği daha ucuz hale getirir.