Nesne Yönelimli Koddan Fonksiyonel Koda: Pratik Refaktör Rehberi
Programlama Paradigmaları
Nesne Yönelimli Koddan Fonksiyonel Koda: Pratik Refaktör Rehberi

Giriş: Neden Fonksiyonel Programlamaya Geçmeli?
Fonksiyonel programlama (FP) ilke ve teknikleri, özellikle test edilebilirlik, daha kolay zihinsel modelleme ve yan etkileri kontrol altında tutma bakımından fayda sağlar. Nesne yönelimli programlama (OOP) ise kapsülleme ve nesne modeliyle karmaşık domainleri ifade etmekte güçlüdür. Her iki paradigmanın farklarını ve nüanslarını özetleyen kaynaklar için bakınız: KodSözlük - Fonksiyonel vs Nesne Yönelimli ve Ichi Pro - İşlevsel Programlamaya Yeniden Düzenleme.
OOP ve FP: Temel Farklar (kısa karşılaştırma)
| Konsept | OOP | FP |
|---|---|---|
| Temel yapı | Sınıflar ve nesneler, durum (state) saklama | Saf fonksiyonlar, veri akışları ve dönüşümler |
| Durum yönetimi | Genellikle yerel veya nesne içi mutable state | İmmutability ve yeni değer üretme ön planda |
| Yan etkiler | Yaygın; metotlar dış dünyayı değiştirebilir | Yan etkiler mümkün olduğunca kenarda tutulur |
| Test edilebilirlik | Duruma bağlı testler gerekebilir | Saf fonksiyonlar birim testlerini kolaylaştırır |
Refaktör Öncesi Hazırlık: Başarılı bir geçiş için kontrol listesi
- Mevcut test kapsamını ölçün; önemli işlevler için birim testleri yazın.
- Durum (state) ve yan etkilerin nerede olduğunu haritalayın: veri tabanı, I/O, global değişkenler, singleton'lar vb.
- Kodun küçük bölümlerini izole edebileceğiniz sınırlar belirleyin (modüller, paketler, servis sınırları).
- Kademeli refaktör planı çıkarın: önce saf fonksiyonları ayırın, sonra state yönetimini ele alın.
- Sürekli entegrasyon (CI) ve otomatik test altyapısını hazırda tutun.
Adım Adım Refaktör: Pratik Örnekler
Aşağıdaki örnekler JavaScript benzeri sözdizimiyle kısa ve anlaşılır olacak şekilde düzenlenmiştir. Amaç mantığı göstermek; kendi proje dilinize çevirin ve test edin.
Örnek 1: Durum (state) taşıyan sınıftan saf fonksiyonlara
// OOP (basitleştirilmiş JavaScript)
class Counter {
constructor(initial = 0) { this.count = initial; }
increment() { this.count += 1; }
get() { return this.count; }
}
Bu yapı içsel state'i değiştiriyor. Fonksiyonel yaklaşıma dönüştürürken state'i fonksiyon dışına çıkarır veya yeni değer döndüren saf fonksiyonlar yazarsınız:
// Fonksiyonel yaklaşım
function increment(count) {
return count + 1;
}
const start = 0;
const next = increment(start);
Veya nesne halinde state tutuyorsanız, immutable dönüşüm:
function incrementState(state) {
return { ...state, count: state.count + 1 };
}
Örnek 2: Yan etkileri kenara çekme (separate side effects)
OOP'te bir metot hem iş mantığını hem de veri tabanı yazmasını yapabilir. Fonksiyonel tasarımda iş mantığını saf fonksiyonlara alır, yan etkileri çağıran kenar kodda gerçekleştirirsiniz.
// OOP
class OrderProcessor {
process(order) {
const validated = this.validate(order);
this.db.save(validated); // yan etki
this.notify(validated); // yan etki
}
}
// Fonksiyonel yön
function validate(order) { /* saf dönüşüm */ }
function transform(order) { /* saf dönüşüm */ }
// Kenarda: persist ve notify gibi yan etkiler çağrılır
const event = transform(validate(order));
persist(event); // yan etki
notify(customer, event); // yan etki
Örnek 3: Koleksiyon dönüşümleri — for döngülerinden map/filter/reduce'e
// OOP tarzı (mutasyon ile)
function getActiveEmails(users) {
const emails = [];
for (let u of users) {
if (u.active) { emails.push(u.email.toLowerCase()); }
}
return emails;
}
// Fonksiyonel tarzı
const emails = users
.filter(u => u.active)
.map(u => u.email.toLowerCase());
Map/filter/reduce gibi fonksiyonel yardımcılar, yan etkisiz küçük fonksiyonlara dayalı temiz dönüşümler sağlar.
İmmutability ve Veri Yapıları
İmmutability, bir veri yapısını değiştirmek yerine onun değiştirilmiş bir kopyasını üretmeyi ifade eder. Bu yaklaşım, eşzamanlılık (concurrency) sorunlarını azaltır ve geçmiş durumları koruyarak hataları izlemeyi kolaylaştırır. Küçük projelerde spread operatörü, Object.assign veya tuple/array kopyalama yeterliyken; büyük ölçekli projelerde kalıcı (persistent) veri yapıları veya özel veri yapısı kütüphaneleri tercih edilebilir. Fonksiyonel yaklaşımların test edilebilirlik katkısı ve immutability önceliği üzerine daha fazla bilgi için bakınız: Ichi Pro.
Test Etme ve Kademeli Geçiş Stratejileri
- Önce saf fonksiyonları ayırarak birim test yazın. Saf fonksiyonların çıktısını girdiyle eşleştirmek kolaydır.
- Yan etki içeren kısımları arayüzlerle/adapterlarla izole edin; bu parçaları mock'lamak daha kolay olur.
- Kademeli refaktör uygulayın: küçük modülleri dönüştürün ve her adımda testleri çalıştırın.
- Geriye dönük uyumluluğu koruyarak paralel yeni API ya da özellik bayrakları (feature flags) kullanabilirsiniz.
Hibrit Yaklaşımlar: Her iki paradigmanın güçlü yanlarını kullanma
Her proje tamamen fonksiyonel ya da tamamen nesne yönelimli olmak zorunda değildir. Hibrit yaklaşımlar, kapsülleme gereken yerlerde OOP, iş mantığı ve dönüşümlerde FP kullanmaya izin verir. Bu tür karışık yaklaşımın pratikliği ve örnekleri için bir tartışma: Ichi Pro - Hibrit Yaklaşımlar.
Sık Karşılaşılan Tuzaklar ve Kaçınma Yolları
- Aşırı soyutlama: Her şeyi fonksiyonel hale getirmeye çalışırken kodu gereksiz karmaşıklaştırmayın. Basitliği koruyun.
- Performans varsayımları: Kopyalama maliyetleri bazı senaryolarda etkili olabilir; ölçün ve gerekiyorsa optimize edin.
- Durumun tamamen ortadan kaldırılması mümkün değilse, durumu iyi tanımlanmış sınırlar içinde tutun.
- Tek seferde tüm kodu dönüştürmeye çalışmayın; küçük adımlarla ilerleyin.
Sonuç: Uygulanabilir Adımlar
- 1–2 kritik modülde saf fonksiyonlar çıkarın ve bunlar için birim testleri yazın.
- Yan etkileri izolasyon katmanlarına taşıyın (örneğin, adapter/port pattern).
- İmmutability uygulamaya başlayın: küçük veri yapılarıyla test edip genişletin.
- Geliştirme akışınıza küçük refaktör adımları ekleyin ve CI ile her adımı doğrulayın.
Kaynaklar ve ileri okumalar
Fonksiyonel Programlama vs Nesne Yönelimli Programlama — KodSözlük
Orada ve Tekrar: İşlevsel Programlamaya Nesne Yönelimli Yeniden Düzenleme — Ichi Pro
İşlevsel Programlama ve Nesne Yönelimli Programlama — Hibrit Yaklaşımlar — Ichi Pro