Sürdürülebilir Refactor Mümkün mü?
Sürdürülebilir şekilde refactor yapamıyoruz, çünkü feci halde kaçırdığımız bir şeyler var.
Giriş
Her yazılım takımında, kıymeti bilinen ama bir türlü tam anlamıyla yerli yerine oturmayan bir meseledir refactoring, yani kodu yeniden düzenleme. Gereksiz Türkçeleştirmenin anlam kaybına ve bağlamdan kopmaya yol açtığını düşündüğüm için, yazı boyunca bu kıymetli meseleden “refactor” veya “refactoring” olarak bahsedeceğim.
Nasıl refactor yapılacağından önce, çözülmesi gereken asıl sorunun refactor’e yönelik bakış açısı olduğunu düşünüyorum.
Refactor, yazılım geliştirmenin ayrılmaz bir parçasıdır!
Refactor’ü, yazılım geliştirmenin doğal sürecinden koparıp başka bir zaman dilimine veya başka bir yere ayırmamız gerektiğine dair yaygın ama yanlış bir inanış var. Oysa ne zaman refactor yaptığımızın farkında olmamız gerekiyor. Çünkü yeni bir özellik eklerken odaklandığımız beklentilerle, refactor sırasında odaklandığımız beklentiler farklıdır. Her iki süreç de tamamlandıktan sonra farklı kriterlere göre değerlendirilmelidir. Ama bu, ikisinin farklı zamanlarda yapılması veya planlanması gerektiği anlamına gelmez. Öncelikle, refactor’ü planlama alışkanlığından kurtulabilir miyiz?
Kulağa sert geliyor, farkındayım. Ancak açıklamama izin verin.
Refactoring, kodun davranışını ve niyetini değiştirmeden, kodu yeniden düzenlemek anlamına gelir. Yıllar boyunca refactor, sadece “göze hoş görünmeyen kodları düzenleme” olarak algılandı. Bu nedenle, çoğu zaman olmasa da olur gözüyle bakıldı. Ve her yazılım geliştiriciye kariyerinde en az bir kez “Çalışıyorsa dokunma!” denildi.
Peki, neden refactor yaparız?
Refactor yapma nedenlerimizi şu şekilde özetleyebiliriz:
Kodu daha anlaşılır kılmak ve sadeleştirmek,
Code smell (kod çürümesi) belirtilerini tespit etmek ve önlemek,
Test edilebilirliği ve bakımı kolaylaştırmak.
Extreme Programming pratiklerini yazılım dünyasına kazandıran Kent Beck şöyle der:
“Öncelikle değişikliği kolaylaştıracak işi yap (ki uyarıyorum, bu kolay olmayacak), sonra kolay olan değişikliği yap.”
Bu, günlük hayatımda kod yazarken sık sık hatırıma gelen bir söz. Umarım sizin de zihninizde yer eder! 🔥
Zamanlama Meselesi
Refactor’ü planlamayı bırakın…
Refactor taskları almayı bırakın…
Refactor için izin almayı bırakın…
Evet, farkındayım, bu söylediklerim kulağa kolay gelmiyor. Ancak biz geliştiriciler bakış açımızı değiştirmedikçe, kimse altın tepside bize refactor için günler sunmayacak. 😏
Peki, doğru yaklaşım nedir?
Geliştirme yaparken refactor yapmalıyız. Gerektiğinde taskların süresini uzatmayı veya kapsamını genişletmeyi göze almalıyız. Ancak bu, geliştirmeyi tamamladıktan, taskı teste, canlıya ya da kim bekliyorsa ona teslim ettikten sonra yapılacak bir şey değil.
Refactor, PR’ı henüz açmadan, geliştirme sürecinin aktif bir parçası olmalıdır. Ancak bu şekilde, refactor’ü yazılım geliştirme döngüsüne sürdürülebilir bir şekilde entegre edebiliriz.
Planlı Refactor’e karşılık Fırsata Dayalı Refactor!
Evet, refactor doğası gereği planlı değil, fırsata dayalı olmalıdır. İşte bu nedenle diyorum ki, refactor taskları almayı tamamen bırakmamız gerekiyor.
Düşünebilirsiniz: “Bu projede alalım, ne olacak? Sonraki projelerde almayız.”
Hayır, bugüne kadar planlı ilerlemiş olabilir, ancak bir noktada bu alışkanlığı bırakmalıyız. Neden mi? Çünkü refactor yapmak bir takım kültürü haline gelmek zorunda.
Eğer bir takım, refactor’ün planlanabilecek bir şey olduğunu düşünürse, içgüdüsel olarak kod yazarken herkes refactor’den kaçınır. Ve neden kaçınmasın ki? Refactor yapmak gerçekten zor! Çalışan kodu durduk yere “mıncıklıyoruz.” 😬 Bir de bu sırada hiç alakası olmayan bir iş yaparken hata veya bulgu sayısı artıyor. Halbuki, taskı tamamlayıp geçmek varken, neden böyle bir risk alalım ki?
Asıl Sorun Ne?
Üzülerek söylüyorum ki biz geliştiricilerin refactor yapmasının önündeki en büyük engel ne sıkışık deadline’lar ne de yönetici bakış açısı. En büyük engel, bizim kendi bakış açımız ve hata yapma korkumuzdur.
Hata yapma korkusunu hafife aldığımı düşünmeyin. Zihinsel olarak güvende ve konforda hissetmediğimiz bir takımda, hata yapma özgürlüğümüzü korumak gerçekten zor. Ancak bu bakış açısını değiştirmediğimiz sürece refactor, yazılım geliştirme döngüsünün dışında kalmaya devam edecek.
Peki Nedir Fırsata Dayalı Refactor?
Fırsata dayalı refactor, geliştirme sürecinin doğal bir parçası olarak, kodun ihtiyaç duyduğu anlarda yapılan düzenlemelerdir. Bu fırsatlar, kod yazarken karşımıza çıkan iyileştirme alanlarıdır ve yazılım yaşam döngüsünün ayrılmaz bir parçasıdır.
1. Preparatory Refactoring
Yani hazırlık refactor’u. Tam da Kent Beck’in sözünü ettiği türden bir refactor.
Bu kavramı en iyi anlatmanın yolu, Martin Fowler’ın blogundaki şu görsel üzerinden geçiyor:
Burada bir başlangıç noktası ve varmaya çalıştığımız bir hedef var. Eğer bu destinasyona bir rotalama uygulamasıyla ulaşmaya çalışsak, muhtemelen bize ağaçlarla ve engebelerle dolu bir arazi yolu önerecektir. Hepimizin başına gelmiştir: “Keşke 5 dakika geç kalsaydık da daha konforlu ve temiz bir yoldan gitseydik!”
Halbuki haritada ikinci bir yol daha var. Hedefin tam aksi yönünde kısa bir mesafe geri giderek bir ana yola ulaşabiliriz. Ve bu ana yol, hedefimize çok daha konforlu bir sürüş olanağı sunar.
İşte bu “aksi yöne” yapılan hamleyi, bir refactor olarak düşünebilirsiniz. İlk bakışta hedefe ulaşmaya hizmet etmiyor gibi görünse de, aslında yeni ve daha kullanışlı bir yol açıyorsunuz. Refactor yaparak task’ın süresini bir miktar uzatabilirsiniz. Ancak günün sonunda ortaya daha temiz bir iş çıkar. Üstelik, sizden sonra o kod üzerinde çalışacak bir geliştirici belki uzun zaman alacak bir işi, sizin refactor’unuz sayesinde çok daha hızlı tamamlayabilir.
Kısacası, Preparatory Refactoring, herhangi bir işi yaparken karşımıza çıkan kod parçalarını geliştirme için daha elverişli hale getirme yaklaşımıdır.
2. Comprehension Refactoring
Kodu daha anlaşılır hale getirmek için yapılan refactor’dür, bunu anlama refactor’u olarak düşünebiliriz. Elimizdeki bir taskı gerçekleştirmek için ilgili kodu okumaya başladığımızda bazen tam bir çileye dönüşebilir. Öyle ki, asıl işi yapmak, değişiklik yapılacak yeri bulmaktan (spelunking/mağaracılık) veya bulduktan sonra anlamaktan çok daha kısa sürebilir. Bu, özellikle belirli bir yaşın üzerindeki codebase’lerde sıkça karşılaşılan bir sorundur.
Genellikle böyle bir durumla karşılaştığımızda, işi yapıp kodun o kısmından hemen çıkmak isteriz. Uzun uğraşlar sonucu kodu anlamış olabiliriz ama emin olun, bir hafta sonra aynı koda döndüğümüzde hiçbir şey hatırlamayıp yeniden anlamaya çalışacağız. Yazdığımız veya okuduğumuz kodu hafızamızda tutmaya çalışmak, boşuna bir çabadır ve sürdürülebilir değildir.
Bu yüzden geliştirme yapmadan önce kodu daha anlaşılır hale getirip, değişikliği bu şekilde yapmak çok daha doğru bir yaklaşımdır. Belki mevcut taskı tamamlamak daha uzun sürer ama aynı koda daha sonra uğrayacak birçok geliştiriciye önemli ölçüde zaman kazandırırsınız.
Ve unutmayın, o geliştiricilerden biri mutlaka siz olacaksınız! 🥳
3. Litter-Pickup Refactoring
Bunu, tek seferde tamamlanamayan bir hazırlık refactor’u olarak düşünebiliriz. Bazen bir kodu anlaşılır veya bakımı kolay hale getirmek düşündüğümüzden çok daha zor olabilir. Böyle durumlarda, çoğu geliştirici hiçbir refactor yapmadan o kodu olduğu gibi bırakıp çıkar. 🙄
Ancak bunun yerine, etraftaki çer çöpü temizleyip yapabileceğimiz kadar refactor yapıp çıkabiliriz. Belki refactor’un tamamını bitiremeyiz, ama kodu bulduğumuzdan daha temiz bırakmak mümkün. İşte Litter-Pickup Refactoring’in temelinde yatan prensip budur: İzci kuralı!
Refactor’un özü, kodu sürekli biraz daha iyi hale getirmektir. Herkes üzerine düşeni yaparsa, zamanla kod tabanı çok daha temiz, düzenli ve sürdürülebilir bir hale gelir. Küçük dokunuşların büyük etkilerini küçümsemeyin!
İyi kodun da refactor’e ihtiyacı var!
Fırsata dayalı refactor’u anlayabilmek adına zamanlamaya göre refactor tiplerini inceledik. İşin özü şu ki, refactor yapmak için en uygun zaman, üzerinde çalıştığımız mevcut bir işin tam da içindeyken harekete geçmektir. Refactor ve geliştirme, iki ayrı şapka gibidir ve her zaman cebimizde durur. Kod yazarken ihtiyaç duyduğumuzda bu şapkalar arasında geçiş yaparak refactor edebiliriz. Kent Beck’in yazılım dünyasına kazandırdığı Two Hat Metaphor (İki Şapka Metaforu), tam olarak bu yaklaşımı temsil eder.
Planlı refactor’un bir diğer tehlikesi, yalnızca kötü kodun refactor’e ihtiyaç duyduğu yanılgısını doğurması ve bu yanılgıyı beslemesidir. Evet, problemli kodları daha iyi hale getirmenin yolu, sürdürülebilir şekilde refactor yapmaktır. Ancak, iyi kodun da refactor’e ihtiyacı vardır! Çünkü iyileştirilmediği sürece, zamanla iyi kod bile problemli bir koda dönüşebilir.
Unutmayın, iyi kod üzerinde refactor yapmak hem daha keyiflidir hem de geliştiriciyi güvende hissettirir.
Kültüre entegre bir refactor bakış açısı gerekiyor!
Refactor, sadece bir kod temizleme işi değil, yazılımın yaşam döngüsünün vazgeçilmez bir parçasıdır. Planlı refactor yanılgısını geride bırakarak, her geliştirme sürecini bir fırsat olarak görmeli ve kodu her seferinde biraz daha iyi hale getirmeye çalışmalıyız. Çünkü iyi yazılım, sürekli iyileştirilen yazılımdır.
Unutmayın, refactor yapmak bir cesaret işidir; hem mevcut kodla yüzleşmeyi hem de daha iyisini hedeflemeyi gerektirir. Bu cesareti gösterdiğinizde, sadece kodu değil, yazılım geliştirme kültürünüzü de dönüştürmüş olursunuz.
Hadi, şapkaları hazırlayın ve kodunuzu bir adım ileriye taşımak için fırsatları değerlendirin! 🎯





