Herkese merhaba! Bu yazıda özellikle büyük çaplı proje geliştirirken sık sık duyduğumuz refactoring ve design pattern terimlerinden ve birbirleri ile olan ilişkilerinden bahsedeceğim. Bir kodun hatasız çalışıyor olması, bakım maliyetinin düşük veya kolayca genişletilebilir olduğu anlamına gelmez. İç içe geçmiş if-else / switch case blokları veya tek başına her şeyi yapmaya çalışan binlerce satırlık “God Class” yapıları, projeni karmaşıklığını ve teknik borcunu inanılmaz derecede artırır. Böyle durumlarla karşılaştığımızda sıfırdan kod yazmak yerine mevcut yapıyı adım adım iyileştirerek yani refactoring uygulayarak doğru design pattern’lara çevirmemiz gerekir. Bu iki terimi detaylı bir şekilde inceleyelim.
Refactoring Nedir?
Çoğu developer “Kodu refactor edeceğim” dediğinde, aslında kodu yeniden yazmayı (rewrite) veya yeniden yapılandırmayı (restructure) kasteder. Koddaki hataları çözmek, veri modellerini değiştirmek veya sisteme yeni davranışlar katmak için çalışmaya başlarlar. Günün sonunda ortaya daha derli toplu bir yapı çıksa da, yapılan bu işlem refactoring değildir.
Martin Fowler’dan alıntı yapmak gerekirse;
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
Yani Fowler, refactoring’in; yazılımın dışarıdan gözlemlenebilir davranışını değiştirmeden, anlaşılabilirliğini artırmak ve bakım maliyetini düşürmek amacıyla iç yapısında yapılan değişiklik olduğunu söyler. Özetle refactoring fonksiyonel bir değişiklik değildir.
- Yeni bir özellik ekleyemezsiniz. Kod dün ne yapıyorsa, bugün de aynısını yapmalıdır.
- Mevcut bug’ları çözemezsiniz. Hata çözmek bir refactor işlemi değil, bug fixing işlemidir.
- Gözlemlenebilir davranışı korumalısınız. Kullanıcı veya sistemi çağıran diğer servisler için hiçbir şey değişmemelidir. Sadece kodun içeriği daha temizlenmiş ve okunabilir hale gelmiştir.
Martin Fowler’ın popülerleştirdiği bir diğer kavram olan “code smell”, bir bug ya da teknik hatayı değil; sistemin tasarımındaki daha derin bir problemin varlığını işaret eder. Tıpkı bir yiyeceğin bozulmadan önce koku yayması gibi; aşırı uzun metotlar, binlerce satırlık şişkin sınıflar veya kendini tekrar eden mantıklar kodun çürümeye başladığını gösterir. Bu durum sistemi anında çökertmez; ancak bakımı zorlaştırarak teknik borcun katlanarak büyümesine neden olur.
Refactoring tam da bu noktada Design Pattern kavramıyla güçlü bir bağ kurar. Kodu iyileştirirken karmaşıklaşan ve bakımı zorlaşan yapıları, yılların tecrübesiyle şekillenmiş mimari şablonlara oturtmak en doğru yaklaşımdır. Kısacası refactoring bir süreç, design pattern’lar ise bu süreçte koda kazandırmak istediğimiz hedef yapıdır.
Design Pattern Nedir?
Design pattern’lar, yazılım tasarımında sıkça karşılaşılan ortak problemlere yönelik geliştirilmiş esnek çözüm şablonlarıdır. Bu kalıplar doğrudan kopyala-yapıştır yapabileceğiniz spesifik kod blokları sunmaz; yaşanan tasarım problemi için soyut ve genel bir mimari konsept sağlar.
Kalıplar genellikle algoritmalar ile karıştırılır. Ancak algoritma, sizi hedefe ulaştıracak net adım ve talimatlar zincirinden oluşurken; tasarım kalıbı daha üst düzey bir mimari yaklaşım sunar. Örneğin, sisteminizde nesne üretim süreçlerini soyutlamak ve kontrol altına almak istediğinizde Creational Patterns (Yaratımsal Kalıplar) devreye girer.

Tasarım kalıpları karşılaşılan problem tiplerine göre 3 başlık altında incelenebilir. Her bir başlığı kendi yazısında ayrıca inceleyeceğiz.
- Creational Patterns: Bu kalıplar esnekliği ve var olan kodun tekrar kullanılabilirliğini artırarak farklı nesne oluşturma mekanizmalarını yönetir.
- Structural Patterns: Bu kalıplar, var olan yapıları esnek ve verimli tutarken; nesnelerin ve sınıfların nasıl bir araya getirileceğini ve daha esnek yapılar kurulacağını açıklar.
- Behavioral Patterns: Bu kalıplar, nesneler arasındaki iletişim protokollerini ve sorumluluk dağılımını organize eder.
Neden Kalıpları Öğrenmeliyiz?
Kalıplar hakkında hiçbir şey bilmeden de bir şekilde yıllarca yazılımcı olarak çalışabilirsiniz. Hatta bilmeden bile bir kalıbı kullanmış olabilirsiniz. Peki o zaman neden kalıpları öğrenmeliyiz?
Çünkü bu kalıplar daha önceden denenmiş ve üzerinde yıllarca geliştirme yapılmış hazır bir toolkit gibidir. Karşılaştığınız bir mimari sorunu sıfırdan çözmeye çalışarak tekerleği yeniden keşfetmek yerine, kendini kanıtlamış bu kalıpları uygulamak geliştirme sürecini ciddi oranda hızlandırır.
Ayrıca büyük çaplı bir projeye dahil olduğunuzda, sizden önce yazılmış mimariyi hızlıca okuyup kavramanızı sağlar. En önemlisi de ekip içi iletişimi kolaylaştırır: Uzun uzun bir algoritma veya tasarım akışı anlatmak yerine “Burada Strategy Pattern kullandık” demek, tüm geliştiricilerin aynı sayfada buluşması için yeterlidir.
Benden bugünlük bu kadar. Bir sonraki yazıya kadar kendinize çok iyi davranın! 😊
Leave a Reply