Nesne Yönelimli vs Fonksiyonel: Basit JavaScript Örnekleriyle Karşılaştırma
Programlama Paradigmaları
Nesne Yönelimli vs Fonksiyonel: Basit JavaScript Örnekleriyle Karşılaştırma

Giriş
JavaScript uygulama geliştirirken sıklıkla iki farklı programlama paradigmasıyla karşılaşırız: Nesne Yönelimli Programlama (OOP) ve Fonksiyonel Programlama (FP). Her iki yaklaşımın da güçlü yönleri ve tipik kullanım alanları vardır. Bu makalede temel farkları açıklayacak, kısa ve çalıştırılabilir örneklerle her iki yaklaşımı gösterecek ve hangi durumlarda hangisinin daha uygun olabileceğine dair pratik öneriler sunacağım.
Nedir? Kısa Tanımlar
Nesne Yönelimli Programlama (OOP): Veriyi ve bu veriyi işleyen fonksiyonları (metotları) nesnelerde birleştirir; kapsülleme, kalıtım ve çok biçimlilik (polymorphism) gibi kavramları öne çıkarır. Bu yaklaşım, gerçek dünyadaki varlıkları modellemeyi kolaylaştırır ve modüler yapı sağlar (Tasarım Kodlama).
Fonksiyonel Programlama (FP): Fonksiyonları birinci sınıf vatandaş olarak ele alır; saf (pure) fonksiyonlar, yan etkilerin azaltılması ve veri dönüşümlerine odaklanma temel ilkeleridir. FP, özellikle veri akışlarını ve dönüşümlerini netleştirmek için kullanışlıdır (KodSözlük).
Pratik Örnek: Aynı Problemin İki Yaklaşımı
Basit bir problem üzerinden gidelim: Bir kullanıcı listesinde "aktif" kullanıcıların yaş ortalamasını hesaplayalım. Önce OOP, sonra FP ile çözelim. Amaç, her iki yaklaşımın kod yapısını ve düşünce biçimini görmektir.
OOP ile Çözüm
class User { constructor(name, age, active) { this.name = name; this.age = age; this.active = active; } isActive() { return this.active; } getAge() { return this.age; } static averageAge(users) { const actives = users.filter(u => u.isActive()); if (actives.length === 0) return 0; const total = actives.reduce((sum, u) => sum + u.getAge(), 0); return total / actives.length; } } const users = [ new User('Ayşe', 30, true), new User('Mehmet', 25, false), new User('Elif', 35, true) ]; console.log(User.averageAge(users)); // 32.5
Açıklama: Bu yapıda User sınıfı veri ve davranışı (metotları) bir arada tutar. averageAge gibi bir yardımcı metot sınıf içinde tanımlanabilir veya ayrı bir servis olarak tutulabilir. Bu düzen, nesnelerin sorumluluklarını netleştirir ve büyük uygulamalarda modellemeyi kolaylaştırır (Medium).
Fonksiyonel Yaklaşım
const users = [ { name: 'Ayşe', age: 30, active: true }, { name: 'Mehmet', age: 25, active: false }, { name: 'Elif', age: 35, active: true } ]; const isActive = u => u.active; const getAge = u => u.age; const average = arr => arr.reduce((a, b) => a + b, 0) / arr.length; const activeAges = users.filter(isActive).map(getAge); const avg = activeAges.length ? average(activeAges) : 0; console.log(avg); // 32.5
Açıklama: FP'de veri genellikle salt nesne veya ham yapıda tutulur; dönüşümler filter, map, reduce gibi saf fonksiyonlarla yapılır. Bu yöntem yan etkileri azaltır ve küçük parçaların birleştirilmesiyle okunabilir boru hatları (pipelines) oluşturur (KodSözlük).
Kısa Karşılaştırma (Hızlı Bakış)
| Özellik | OOP | FP |
|---|---|---|
| Veri ve Davranış | Birleşik (nesnelerde metotlar) | Veri dönüşümleri ayrı saf fonksiyonlar |
| Yan Etkiler | Daha fazla içerebilir; iyi tasarım ile sınırlanır | Yan etkiler azaltılır; saf fonksiyonlar tercih edilir |
| Yeniden Kullanılabilirlik | Sınıflar ve kalıtımla modelleme | Fonksiyon kompozisyonu ve yüksek-dereceli fonksiyonlar |
| Tipik Kullanım | Domain modelleme, büyük nesne grafikleri | Veri dönüşümleri, eşzamansız veri akışları |
Ne Zaman Hangi Yaklaşımı Seçmeli?
Genel bir kural yoktur; seçim uygulamanın doğasına, takım tecrübesine ve bakım gereksinimlerine bağlıdır. Ancak pratikte şu rehber yardımcı olur:
- OOP tercih edilebilir — karmaşık domain modelleri, nesne ilişkileri ve açık yaşam döngüsüne sahip varlıklar (ör. oyun objeleri, iş domaini modelleri).
- FP tercih edilebilir — veri dönüşümleri, boru hattı hâlindeki işlemler, hataya dayanıklı ve test edilebilir küçük fonksiyon kümeleri.
- Karma kullanım — JS dünyasında sık görülen yaklaşımdır: sınıfları veri modelleri için, saf fonksiyonları ise dönüşümler, yardımcı işlemler ve testlerde kullanabilirsiniz (DEV Community).
Geçiş Stratejileri ve Pratik İpuçları
Aşağıda hem OOP hem FP ile daha sürdürülebilir kod yazmanıza yardımcı olacak adımlar var:
- Her fonksiyonun tek bir sorumluluğu olsun; küçük, test edilebilir parçalara ayırın.
- Yan etkileri görünür hale getirin: veriyi doğrudan değiştirmek yerine yeni veri yapıları döndürün.
- Sınıfları kullanırken SRP (Single Responsibility Principle) ilkesiyle hareket edin; sınıflar birden fazla sorumluluk taşımasın.
- FP tekniklerini kademeli olarak uygulayın: reducer'lar, saf yardımcı fonksiyonlar ve yüksek-dereceli fonksiyonlarla başlayın.
- Test yazmayı alışkanlık haline getirin; saf fonksiyonların testi genellikle daha kolaydır.
Uygulama Adımları (Checklist)
- Problem tanımını yapın: Hangi veriler ve işlemler var?
- Modelleme kararları alın: Nesne mi, veri yapısı mı?
- Fonksiyonları küçük tutun; yan etkileri sınırlayın.
- Karma yapı kullanıyorsanız sınırları netleştirin (ör. domain mantığı sınıflarda, dönüşümler saf fonksiyonlarda).
- Kod gözden geçirmeleriyle stil ve sorumlulukları kontrol edin.
Sonuç ve Öneriler
OOP ile FP arasındaki tercih, genellikle "hangisi daha iyi" sorusundan ziyade "hangi durumda daha uygun" sorusuna bağlıdır. OOP, gerçek dünya modellemelerinde ve karmaşık objeler arası ilişkilerde güçlüdür; FP ise veri dönüşümleri ve test edilebilir küçük fonksiyon kümelerinde avantaj sağlar. Gerçek dünyada birçok proje her iki paradigmayı bir arada kullanır; önemli olan, her yaklaşımın güçlü taraflarını projenize uygun şekilde entegre etmektir (Tasarım Kodlama, KodSözlük).
Başlangıç için önerim: Önce temel JavaScript kavramlarına hâkim olun, ardından küçük projelerde her iki yaklaşımı deneyin. Hangi yöntemin belirli bir problem için daha uygun olduğunu tecrübe ederek öğrenmek genellikle en hızlı yoldur.