Kodun Yeniden Düzenlemesi — 1
Bir zamanlar, bir danışman, bir yazılım geliştirme projesini ziyaret etti.

- Bu yazı Refactoring kitabından alıntıdır. Orjinal halini buradan alabilirsiniz.
Danışman, yazılan kodların bir kısmına baktı, sistemin merkezinde sınıf hiyerarşisi vardı. Hiyerarşi üzerinde gezerken, bunun ne kadar karmaşık olduğunu gördü. Üst-düzey sınıflar, sınıfların nasıl çalışacağı konusunda kalıtsal kod(inherited code) üzerinde somutlaşmış varsayımlar yapıyordu. Bu kod, tüm alt-sınıflara uymuyordu ama alt-sınıflar tarafından çokça yerde geçersiz kılınmıştı(overriding). Üst sınıfı biraz değiştirme imkanı olsaydı, o zaman bu kadar geçersiz kılmaya ihtiyaç duymazdı. Üst-sınıfın amacının düzgün şekilde anlaşılmadığı diğer yerlerde, üst-sınıfın davranışı çoklanılmıştı. Daha da başka yerlerde de, birkaç alt-sınıf başka kodlarla aynı şeyi yapıyordu, ki bu kodlar hiyerarşide açıkça yer değişebilir olanlardı.
Danışman, proje yönetimine koda bakınılıp, temizlenmesini tavsiye etti, ama proje yönetimi bu konuda istekli değildi. Kod çalışıyor görünüyordu ve proje üzerinde zaman baskısı vardı. Yöneticiler, daha ileri noktada kodu toparlayacaklarını söylediler.
Danışman, ayrıca programcılara çalıştıkları hiyerarşi üzerinde neler olup bittiğini gösterdi. Programcılar istekliydiler ve problemin ne olduğunu anladılar. Bunun tamamen kendi hataları olmadığını biliyorlardı, bazen yeni bir çift göz problemi ortaya çıkarmak için gerekebiliyordu. Daha sonra programcılar, hiyerarşiyi temizlemek için bir iki gün harcadılar. İşlerini bitirdiklerinde, işlevselliği bozmadan hiyerarşideki kodun yarısını temizlemişlerdi bile. Sonuçtan gayet memnunlardı, hiyerarşiye yeni sınıf eklemek ve bu sınıfları sistemin geri kalanında kullanmak, artık çok daha hızlı ve kolay olmuştu.
Proje yönetimi bu durumdan memnun değildi. Zaman kısıtlıydı ve daha yapılacak çok iş vardı. Bu iki programcı, iş yapmak için gereken iki günü harcamışlardı ama birkaç ay sonra dağıtımı yapılacak sistem için yeni özellik eklemeyle ilgili hiçbir şey yapmamışlardı. Eski kod gayet iyi çalışıyordu. Belki öncekine göre tasarım biraz daha saf ve temizdi ama yine de projenin çalışan kodun dağıtımının yapılması gerekiyordu, akademiyi memnun etmesi gereken koda ihtiyaç yoktu. Danışman, temizleme işinin sistemin merkezi diğer yerlerinde de yapılması gerektiğini tavsiye etti. Bu tür karar, projeyi bir ya da iki hafta durdurabilirdi. Bütün bu faaliyetler kodun daha iyi görünmesi içindi, yoksa daha önce yapamadığı şeyi yapabilmesi için değildi.
Bu hikayede, danışman daha fazla temizlik tavsiye etmek de haklı mıydı? Yoksa eski bir mühendislik atasözünde dendiği gibi, “çalışıyorsa, dokunma” demek mi gerekiyordu.
Burada ki danışman, kitabın yazarı Martin Fowler idi. Altı ay sonra proje başarısız oldu. Bunun başlıca sebebi, kodun, hata ayıklamak ve performansı kabul edilebilir bir seviyeye getirmek için, çok karmaşık olmasıydı.
Projeyi tekrar başlatmak için danışman olarak Kent Beck getirildi. Bütün sistem neredeyse baştan yazıldı. Kent Beck, birçok şeyi farklı şekilde yaptı. En önemlilerinden bir tanesi, yeniden düzenleme(refactoring) ile sürekli bir şekilde kodu temiz tutmada, ısrarcı olmasıydı. Projenin başarılı olması ve yeniden düzenlemenin bu başarıda oynadığı rol, bu kitabın yazılmasında ilham oldu. Böylece kitap aracılığıyla bilgiyi aktaracak ve yeniden düzenleme ile yazılımın kalitesini artırmanın yollarını gösterecektim.
Yeniden Düzenleme(Refactoring) Nedir?
Yeniden düzenleme, bir yazılım sistemini, kodun dış davranışını değiştirmeden iç yapısının kalitesini artırma yoluyla, değiştirme sürecidir.
Kodu temizlemenin disiplinli yoludur, bu sayede hatalarının ortaya çıkma ihtimali en aza indirgenir. Özünde, yeniden düzenleme yaptığınızda, kodun yazıldığı andan itibaren kod tasarımının iyileştirirsiniz.
“Kodun yazıldığı andan itibaren kod tasarımını iyileştirmek.” Bu garip bir ifade oldu gibi. Mevcut yazılım geliştirme anlayışımızda, önce tasarlayıp sonra kodlamaya inanırız. İyi tasarım önce gelir, kodlama sonra gelir. Zamanla kod değişir ve sistemin bütünlüğü ile bu tasarıma göre onun iç yapısı kademeli olarak kaybolur. Kod yavaşca mühendislikten korsanlığa doğru kaymaya başlar.
Yeniden düzenleme bu pratiğin tam tersidir. Yeniden düzenleme ile kötü tasarımı hatta kaosu alırsın ve onu iyi-tasarlanmış koda çevirirsin. Her bir adım çok basittir. Bir alanı bir sınıftan diğerine taşırsın, bazı kodları metoddan dışarı çıkarıp kendi metodunu oluşturursun ve bazı kodları hiyerarşide yukarı-aşağı kaydırırsın. Bu ufak değişikliklerin toplam etkisi, radikal şekilde tasarımı iyileştirir. Yazılım bozulmasıyla ilgili normal genel görüşün tam tersi bir durum oluşur.
Yeniden düzenleme ile işte değişiklik yapmanın dengesini bulursunuz. Tasarımın, sadece en başta değil, geliştirme sırasında bile sürekli oluştuğunu bulursunuz. Ortaya çıkan etkileşim, geliştirme devam ettiği müddetçe, her zaman iyi bir tasarıma sahip programa yönlendirir.
İlk Örnek
Yeniden düzenleme anlatmaya nasıl başlanır? Bunun geçmişinden bahsedersek insanlar uyuklamaya başlarlar. En iyi yöntem bir örnek vermektir. Örnekler insanları uyandırır, örnekle neler olduğunu anlamak daha kolaydır. Bu yüzden bir örnekle başlıyoruz.
Giriş örneğiyle ilgili şöyle bir problem vardır. Büyük bir program seçilip anlatılır ve nasıl yeniden düzenlendiği gösterilirse, okuyucuların takip etmesi için çok karmaşık olur. Bununla birlikte, basitçe hemen anlaşılan ufak bir program seçersem de, yeniden düzenlemenin buna değecek bir şey olmadığı anlaşılır.
Bu yüzden, gerçek dünya programları için faydalı teknikleri tanımlamak isteyen insanların kategorisinde yer aldım. Aslında göstereceğim gibi ufak bir programda, yeniden düzenleme yapmaya çalışmak gereksizdir ama göstereceğim kod büyük bir sistemin parçası olsaydı, yeniden düzenleme artık çok önemli olurdu. Bu yüzden örneğin daha büyük bir sistem kapsamında değerlendirilmesi gerekiyor.
Başlangıç Noktası
Örneğimiz, video film mağazasında, müşterinin ücretini hesaplayan ve bunları bir çıktı şeklinde yazdıran bir program. Müşterinin hangi filmi ne kadar süre kiralayacağı söylenir. Sonra program süreye ve filmin tipine göre bir ücret hesaplar. Üç tür film vardır, normal, çocuklar için ve yeni çıkanlar. Ücretleri hesaplamanın yanında, üretilen çıktı, kiracı sıklık puanlarını hesaplar, bu da filmin yeni sürüm olup olmadığına göre değişir.
UML diyagramı aşağıdaki gibi olur.

Sınıfların kodları da şu şekilde olur.
Movie Sınıfı
Sadece veri sınıfı olarak görev alır.
Rental Sınıfı
Müşterinin kiraladığı filmleri tutar.
Customer Sınıfı
Mağazanın müşterini tutar.
Başlangıç Programı Hakkında Yorumlar
Programın tasarımı hakkında ki ilk izleniminiz nedir? İyi-tasarlanmamış ve nesne-yönelimli değil diyebiliriz. Bu tür küçük bir program için, bu çok da önemli değildir ama daha karmaşık bir sistemi temsil eden bir parça olsaydı, gerçekten büyük problemlerimiz olurdu. Customer sınıfı içindeki statement metodu çok fazla şey yapıyor. Başka sınıflar tarafından yapılması gereken birçok şey dahi yapıyor.
“Program çalışıyor” ne de olsa düşünebilirsiniz ama bu sadece sistemde bir şeyler değiştirene kadardır. Derleyici kodun kötü ya da temiz olmasını önemsemez. Sistemi değiştirdiğimizde ve insanlar işe dahil olduklarında, insanlar önemserler. Kötü tasarlanmış sistemi değiştirmek zordur. Zordur, çünkü değişikliğin nerede gerektiğini bulmak zordur. Ne değiştireceğini bulmak zor ise, programcıların hata yapması ya da üretmesi yüksek ihtimaldir.
Bu kod örneğinde, kullanıcıların yapmak istediği değişiklikleri biz yapacağız. statement metodunun ürettiği çıktıyı HTML formatında üreteceğiz ki, böylece Web’te de kullanılabilsin. Bunu yapmadığımız takdirde, insanlar bu davranışı çoklayan yeni bir metod yazma yoluna giderler. Bu çok da zahmetli bir iş değildir. statement metodunu kopyala ve içinde istediğin değişikliği yap.
Ya ücretlendirme kurallarıyla ilgili bir değişiklik olursa? Bu durumda hem statement hem de htmlStatement metodlarını düzeltmek gerekiyor. Kopyala-yapıştır işlemindeki asıl problem, onları daha sonra değiştirmek istediğinde meydana gelir. Programınızın değişmesini beklemiyorsanız, kopyala-yapıştır sorun oluşturmaz. Ama programınızın uzun vadede çalışmasını düşünüyorsanız, kopyala-yapıştır bir tehdite dönüşür.
Bu da bizi ikinci değişikliğe götürür. Kullanıcılar, filmleri sınıflandırma biçimlerinde değişiklik yapmak istiyorlar ama değişikliğin ne olduğuna henüz karar vermemişler. Kafalarında birçok değişiklik var. Bu değişiklikler, kiracıların filmler için ne kadar ücret ödeyeceklerini ve kiracı sıklık puanının nasıl olacağını etkiler. Deneyimli bir geliştirici isen, sana verilen kullanıcı şeması her ne ise, onun altı ay içinde değiştirileceğini bilirsin.

Sınıflandırma veya ücret kurallarında bir değişiklik olursa, kodun değişeceği yer statement metodudur.
Program için değişikliği en az yapma dürtünüz, size ağır basabilir. Eski bir mühendis deyimi vardır, “bir şey bozuk değilse, onu tamir etme.” Programlar bozulmayabilir ama yine de insanları yaralar. Kullanıcıların istediği değişikliği yapmak çok zor bir hale geldiğinde, senin de yaşamın daha zor hale gelir. Tam bu durumda, yeniden düzenleme(refactoring) devreye girer.
Bir programa bir özellik ekleyeceğin zaman, bu özelliği eklemek için program uygun şekilde yapılandırılmadıysa, ilk önce programı, özelliği eklemeyi kolaylaştıracak şekilde, yeniden düzenleyin, daha sonra bu özelliği ekleyin.

