Decorators (ES7+) – Fonksiyonlara ve Class’lara Süper Güç Verme 🦸‍♂️✨

JavaScript Rehberi

JavaScript’te bazen bir fonksiyona ya da class’a ekstra güçler eklemek isteriz. Mesela:

  • Her çağrıldığında loglasın
  • Parametreleri otomatik kontrol etsin
  • Ağır hesaplamaları önbelleğe alsın

Ama her seferinde fonksiyonun içine bu kodları eklemek… 😵‍💫 Kod cehennemi!

İşte Decorators burada devreye giriyor: Kodun içine dokunmadan fonksiyon veya class’a süper güçler eklemenizi sağlar.


🧩 1. Decorator Nedir?

Decorator = bir fonksiyonu veya class’ı alan ve onu geliştiren sihirli fonksiyon.

  • Fonksiyon veya class değişmez
  • Decorator ekstra özellik ekler
  • Tekrar kullanılabilir ve temiz kod sağlar

Analojisi:

  • Fonksiyon = bir kahraman 🦸
  • Decorator = kahramana verilen sihirli pelerin
  • Sonuç = süper kahraman 💥

🔹 2. Basit Örnek: Logging Decorator

Senaryo: Fonksiyon çağrıldığında log basmak

Normal JS ile:

function selamla(name) {
  console.log(`Merhaba ${name}!`);
  console.log("selamla fonksiyonu çağrıldı!");
}

selamla("Ali");

⚠️ Problem: Eğer 50 fonksiyonun varsa, hepsine eklemen gerekir 😵
Çok tekrarlı ve bakımı zor.


Decorator ile:

function log(target, key, descriptor) {
  const original = descriptor.value; // Orijinal fonksiyon
  descriptor.value = function(...args) {
    console.log(`${key} çağrıldı, argümanlar: ${args}`);
    return original.apply(this, args); // Orijinal fonksiyon çalışıyor
  };
  return descriptor;
}

class Selamlayici {
  @log
  selamla(name) {
    console.log(`Merhaba ${name}!`);
  }
}

const s = new Selamlayici();
s.selamla("Ali");

✅ Çıktı:

selamla çağrıldı, argümanlar: Ali
Merhaba Ali!

📌 Detaylı açıklama:

  • @log → fonksiyona süper güç ekler ✨
  • target → fonksiyonun ait olduğu obje veya class
  • key → metodun adı
  • descriptor.value → orijinal fonksiyon
  • apply(this, args) → fonksiyonu kendi argümanlarıyla çalıştırır

💡 Pratik ipucu: Logging decorator’ları debug sırasında hayat kurtarır.


🧠 3. Validation Decorator

Bazı fonksiyonlar güvenli olmalı: parametrelerin eksik veya hatalı gelmesini engelle.

function validate(target, key, descriptor) {
  const original = descriptor.value;
  descriptor.value = function(name) {
    if (!name) {
      throw new Error("İsim gerekli!");
    }
    return original.apply(this, [name]);
  };
  return descriptor;
}

class KullaniciSelamlayici {
  @validate
  selamla(name) {
    console.log(`Selam ${name}!`);
  }
}

const u = new KullaniciSelamlayici();
u.selamla(""); // ❌ Hata: İsim gerekli!
u.selamla("Ayşe"); // ✅ Selam Ayşe!

📌 Eğlenceli örnek:
Bu decorator = fonksiyona kapı bekçisi ekler 🚪
İsim yoksa “geçemezsin!”

💡 İpucu:

  • Validation decorator’ları form girişleri, kullanıcı verileri gibi yerlerde hayat kurtarır
  • Kod tekrarı ortadan kalkar

🧩 4. Caching (Önbellek) Decorator

Bazı fonksiyonlar ağır işlemler yapar.
Decorator ile sonuçları saklayabilir, tekrar çağrıldığında süper hızlı geri dönebilirsin ⚡

function cache(target, key, descriptor) {
  const original = descriptor.value;
  const memory = {};
  descriptor.value = function(num) {
    if(memory[num] !== undefined) {
      console.log(`Cache’den alındı: ${num}`);
      return memory[num];
    }
    const result = original.apply(this, [num]);
    memory[num] = result;
    return result;
  };
  return descriptor;
}

class Hesaplayici {
  @cache
  factorial(n) {
    console.log(`Hesaplanıyor: ${n}!`);
    return n <= 1 ? 1 : n * this.factorial(n - 1);
  }
}

const h = new Hesaplayici();
console.log(h.factorial(5)); // Hesaplanıyor…
console.log(h.factorial(5)); // Cache’den alındı!

📌 Detaylı açıklama:

  • memory → önbellek nesnesi
  • Eğer sonuç daha önce hesaplanmışsa memory kullanılır
  • apply → orijinal fonksiyonun çalışmasını sağlar

💡 Pratik ipucu:

  • CPU yoğun işlemlerde süper zaman kazandırır
  • Cache decorator’ını API çağrıları veya matematiksel hesaplamalar için kullanabilirsin

🧠 5. Decorator’ları Kombine Etmek

  • Bir fonksiyon hem logging, hem validation, hem caching decorator’larını alabilir
  • Sıralamaya dikkat: önce validation → sonra caching → sonra logging, mantıklı olur
class SuperSelam {
  @log
  @cache
  @validate
  selamla(name) {
    console.log(`Selam ${name}!`);
  }
}

Not: Decorator’lar yukarıdan aşağıya uygulanır, bu sırayı bilmek önemli


🎉 6. Decorator Kullanım Kuralları ve İpuçları

  • Tekrar kullanılabilir olmalı
  • Fonksiyon veya class’ı değiştirmemeli
  • Karmaşık kodu temizler, okunabilirliği artırır
  • Süper güçleri kombinlemek mümkün

💡 Bonus İpucu:

  • Logging + Validation + Caching = “Fonksiyon Süper Kahramanı”
  • Yeni JS projelerinde modern, temiz ve sürdürülebilir bir yöntemdir

🎯 7. Sonuç: Decorator’lar Seni JS Süper Kahramanı Yapıyor

  • Kod kısa, temiz, okunabilir
  • Fonksiyonlara veya class’lara ekstra özellikler ekleyebilirsin
  • Logging, validation, caching gibi tekrar eden işleri otomatikleştirir
  • Kendini JavaScript süper kahramanı gibi hissedersin 🦸‍♂️✨

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir