Tasarım Kalıpları Ne Zaman Gerekli?

## Tasarım Kalıpları Gerçekten Ne Zaman Gerekli? Tasarım kalıpları, tekrar eden tasarım problemlerine yönelik denenmiş çözüm şablonlarıdır. Ancak her...

Tasarım Kalıpları Ne Zaman Gerekli?

Tasarım Kalıpları Gerçekten Ne Zaman Gerekli?

Tasarım kalıpları, tekrar eden tasarım problemlerine yönelik denenmiş çözüm şablonlarıdır. Ancak her problem için bir kalıp uygulamak, kodu iyileştirmek yerine karmaşıklaştırabilir. Bu rehber, orta seviye geliştiricilerin bir kalıbı ne zaman uygulayıp ne zaman uygulamayacağına dair pratik bir karar çerçevesi sunar.

Önkoşul olarak nesne yönelimli programlama (sınıf, arayüz, kalıtım, kompozisyon) ve en az bir dilde (örneklerde TypeScript kullanılacak) arayüz/soyutlama kavramlarına aşina olmanız beklenir. Kalıplar dilden bağımsızdır; verilen kod örnekleri kavramsal gösterim amaçlıdır ve belirli bir kütüphane sürümüne bağlı değildir.

Önce Problemi Tanımla, Sonra Kalıba Bak

Kalıp seçimi bir tasarım kararıdır ve şu sırayla ilerlemelidir:

  1. Değişen şeyi belirle. Kodun hangi kısmı sık değişiyor veya değişmesi bekleniyor?
  2. Değişimi soyutla. Değişen davranışı bir arayüz arkasına al.
  3. Kalıbı en son adımda düşün. Kalıp, soyutlamanın doğal sonucu olarak ortaya çıkıyorsa uygundur; zorla uygulanıyorsa gereksizdir.

Bu sıralamayı atlayıp doğrudan "buraya Factory koyalım" demek, kalıbı probleme değil probleme kalıbı uydurmaya götürür.

Kalıbın Maliyeti Var

Her kalıp ek sınıf, dolaylılık (indirection) ve okuma yükü getirir. Bir kalıbı uygulamadan önce şu soruları sorun:

  • Bu değişkenlik gerçekten var mı, yoksa varsayımsal mı? Gelecekte ihtiyaç duyulabilir diye eklenen soyutlama genellikle YAGNI (You Aren't Gonna Need It) ihlalidir.
  • Ekip bu kalıbı tanıyor mu? Tanınmayan bir kalıp, kazançtan çok kafa karışıklığı üretebilir.
  • Basit bir çözüm yeterli mi? Bir if/else veya fonksiyon parametresi ile çözülebilen şey için tam bir kalıp gereksiz olabilir.

Sık Kullanılan Kalıplar ve Uygun Bağlamlar

Strategy: Değişen Algoritmayı Ayır

Aynı işi farklı yollarla yapan ve çalışma zamanında seçilmesi gereken algoritmalarınız varsa Strategy uygundur. Uygunsuz kullanım, yalnızca iki sabit seçenek için tam bir hiyerarşi kurmaktır.

interface ShippingStrategy {
  calculate(weightKg: number): number;
}

class StandardShipping implements ShippingStrategy {
  calculate(weightKg: number): number {
    return weightKg * 5;
  }
}

class ExpressShipping implements ShippingStrategy {
  calculate(weightKg: number): number {
    return weightKg * 12 + 20;
  }
}

class ShippingCalculator {
  constructor(private strategy: ShippingStrategy) {}

  total(weightKg: number): number {
    return this.strategy.calculate(weightKg);
  }
}

Beklenen davranış: ShippingCalculator'a hangi strateji verilirse total o stratejinin hesabını döndürür. Yeni bir kargo türü eklemek, mevcut sınıfları değiştirmeden yeni bir ShippingStrategy implementasyonu yazmakla mümkün olur.

Factory: Nesne Oluşturmayı Merkezileştir

Nesne oluşturma mantığı karmaşıksa veya çağıran tarafın somut sınıfı bilmesi istenmiyorsa Factory kullanışlıdır. Tek bir new çağrısı için Factory eklemek gereksizdir.

Observer: Olay Yayılımını Çöz

Bir nesnedeki değişiklik birden fazla bileşeni ilgilendiriyorsa ve bu bileşenler doğrudan birbirine bağlanmamalıysa Observer uygundur. Aboneliklerin temizlenmemesi (unsubscribe edilmemesi) bellek sızıntısına yol açar; bu kalıbın en yaygın tuzağıdır.

Decorator: Davranışı Katmanla Ekle

Kalıtım patlamasını (çok sayıda alt sınıf kombinasyonu) önlemek için davranışı çalışma zamanında katmanlamak istediğinizde Decorator uygundur. Aşırı katmanlama, hata ayıklamayı zorlaştırır.

Yaygın Hatalar

  • Erken soyutlama: İkinci bir kullanım ortaya çıkmadan kalıp kurmak. Kural olarak, aynı değişkenliği en az iki gerçek senaryoda görmeden soyutlama eklemeyin.
  • Kalıbı amaç sanmak: "Temiz kod" görünsün diye kalıp eklemek; sonuç, ihtiyaçtan fazla sınıf ve dolaylılıktır.
  • Singleton'ı global durum için kullanmak: Test edilebilirliği ve eşzamanlılığı bozar. Bağımlılığı enjekte etmek genellikle daha iyidir.
  • Kalıp isimlerini zorlaştırmak: Sınıf adlarına Manager, Helper, Factory eklemek anlamı netleştirmiyorsa, adlandırma problemi çözmüyordur.

Güvenlik Etkileri

Kalıpların güvenlik üzerinde dolaylı etkileri olabilir:

  • Singleton ve paylaşılan durum: Global erişilebilir tekil nesneler, yetkisiz erişime açık durum tutabilir. Erişim kontrolünü ayrıca düşünün.
  • Factory ile nesne oluşturma: Doğrulama yapılmadan nesne üretilirse, geçersiz veya kötü niyetli girdi içeri sızabilir. Girdi doğrulamasını oluşturma noktasında yapın.
  • Observer zincirleri: Olay verisi birçok aboneye yayılır; hassas verinin gereksiz abonelere gitmediğinden emin olun.
  • Decorator katmanları: Ara katmanlarda yapılan loglama, hassas veriyi (token, parola) yanlışlıkla kaydedebilir.

Karar Kontrol Listesi

Bir kalıbı uygulamadan önce şunları netleştirin:

  • Çözmeye çalıştığınız somut problem nedir?
  • Bu problem en az iki gerçek senaryoda tekrar ediyor mu?
  • Daha basit bir çözüm (fonksiyon, parametre, kompozisyon) yeterli mi?
  • Eklediğiniz soyutlama, gelecekteki değişimi gerçekten kolaylaştırıyor mu?
  • Ekip bu kalıbı okuyup bakımını yapabilecek mi?

Bu sorulara net cevap veremiyorsanız, kalıbı ertelemek genellikle doğru karardır. Tasarım kalıpları, problem ortaya çıktığında başvurulacak araçlardır; problemden önce kurulacak hedefler değil.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz