Web Geliştirmede `switch` Kullanmadan Daha Temiz ve Okunabilir Kod Yazmanın 5 Yolu 
Selam dostlar!
Uzun süredir forumda takılıyorum ve sık sık karşılaştığım bir durumdan bahsetmek istiyorum: karmaşık `switch` veya `if-else if` merdivenleri. Özellikle yeni başlayan arkadaşlar, bir değişkenin değerine göre farklı işlemler yapmak için hemen `switch`'e sarılıyorlar. Ancak projeler büyüdükçe, bu yapılar bakımı zor, okunması güç ve genişletilmesi sancılı bir hal alabiliyor. 
Bugün, bu geleneksel yaklaşıma alternatif, daha modern ve temiz 5 farklı teknikten bahsedeceğim. Bu yöntemlerle kodunuz daha modüler, test edilebilir ve anlaşılır olacak. Hadi başlayalım!
1. Nesne Literalleri (Object Literals) ile Eşleme
Bu belki de en sık kullanılan ve en zarif çözüm. Anahtar-değer çiftlerini kullanarak, her bir durum için çalıştırılacak fonksiyonu veya değeri bir nesne içinde tanımlayabiliriz.
Örnek bir `switch` yapısını dönüştürelim:
2. Map Nesnesi ile Daha Güçlü Anahtarlar
`Object` literalleri güzel, ancak anahtar olarak sadece string veya Symbol kabul eder. Eğer anahtarlarınız fonksiyon, nesne veya herhangi bir değer olacaksa, `Map` nesnesi mükemmel bir çözümdür.
3. Polymorphism (Çok Biçimlilik) ve Strateji Tasarım Deseni
Bu, nesne yönelimli programlamanın gücünü kullanan, ölçeklenebilirlik açısından en güçlü yöntemlerden biridir. Her bir durumu ayrı bir sınıf veya nesne ile temsil ederiz.
4. Fonksiyonların Doğrudan Kullanımı ve Yüksek Mertebeden Fonksiyonlar
Bazen en basit çözüm en iyisidir. Eğer koşullarınız basitse ve her biri bir fonksiyonu tetikliyorsa, bu fonksiyonları doğrudan bir dizide veya başka bir yapıda saklayıp, koşula göre çağırabilirsiniz.
5. Dinamik Fonksiyon Çağrıları (Çok Dikkatli Kullanın!)
Bu yöntem biraz daha ileri seviye ve dikkat gerektirir. Fonksiyon isimleriniz, gelen değerle aynı formatta ise, bu fonksiyonları dinamik olarak çağırabilirsiniz. Ancak güvenlik risklerine açıktır, sadece güvendiğiniz, kontrolünüz altındaki verilerle kullanın.
Sonuç: Doğru Aracı Doğru Yerde Kullanın
Unutmayın, amaç sadece `switch`'ten kurtulmak değil. Amaç daha okunabilir, test edilebilir, sürdürülebilir ve esnek kod yazmaktır.
Bir sonraki `switch` yazmaya başladığınızda, durun ve "Bunu daha temiz bir yapıya dönüştürebilir miyim?" diye kendinize sorun.
Umarım bu rehber işinize yarar. Forumda görüşmek üzere, kodunuz temiz, hatasız olsun!
*Bu makaledeki teknikler genellikle "Conditional Logic"ı daha yönetilebilir hale getirmek için kullanılan yaygın pattern'lerdir.*
Selam dostlar!
Bugün, bu geleneksel yaklaşıma alternatif, daha modern ve temiz 5 farklı teknikten bahsedeceğim. Bu yöntemlerle kodunuz daha modüler, test edilebilir ve anlaşılır olacak. Hadi başlayalım!
1. Nesne Literalleri (Object Literals) ile Eşleme
Bu belki de en sık kullanılan ve en zarif çözüm. Anahtar-değer çiftlerini kullanarak, her bir durum için çalıştırılacak fonksiyonu veya değeri bir nesne içinde tanımlayabiliriz.
- Avantajı: Çok hızlıdır (O(1) karmaşıklık), okuması kolaydır ve yeni durumlar eklemek çok basittir.
- Dikkat Edilmesi Gereken: Varsayılan bir durum (`default`) eklemek için biraz daha düşünmek gerekebilir.
Örnek bir `switch` yapısını dönüştürelim:
Kod:
// ESKİ YOL (switch)
function getMeyveRengi(meyve) {
let renk;
switch (meyve) {
case 'elma':
renk = 'kırmızı';
break;
case 'muz':
renk = 'sarı';
break;
case 'üzüm':
renk = 'mor';
break;
default:
renk = 'bilinmiyor';
}
return renk;
}
// YENİ & TEMİZ YOL (Nesne Literali)
function getMeyveRengiTemiz(meyve) {
const renkMap = {
'elma': 'kırmızı',
'muz': 'sarı',
'üzüm': 'mor'
};
// '??' (Nullish Coalescing) operatörü ile varsayılan değer
return renkMap[meyve] ?? 'bilinmiyor';
}
// Veya fonksiyon çalıştırmak istersek:
const islemMap = {
'topla': (a, b) => a + b,
'cikar': (a, b) => a - b,
'carp': (a, b) => a * b
};
function hesapYap(islem, a, b) {
const fonksiyon = islemMap[islem];
return fonksiyon ? fonksiyon(a, b) : 'Geçersiz işlem';
}
2. Map Nesnesi ile Daha Güçlü Anahtarlar
`Object` literalleri güzel, ancak anahtar olarak sadece string veya Symbol kabul eder. Eğer anahtarlarınız fonksiyon, nesne veya herhangi bir değer olacaksa, `Map` nesnesi mükemmel bir çözümdür.
- Avantajı: Anahtar tipleri konusunda esnektir, anahtarları kolayca iterate edebilirsiniz (`.keys()`, `.values()`).
- Dikkat Edilmesi Gereken: JSON'a doğrudan dönüştürülemez.
Kod:
const islemMap = new Map();
// Anahtarlar herhangi bir değer olabilir
const TOPLA = Symbol('topla');
const USER_ROLE = { id: 1, name: 'admin' };
islemMap.set(TOPLA, (a, b) => a + b);
islemMap.set(USER_ROLE, () => console.log('Admin işlemi'));
islemMap.set(404, () => 'Sayfa Bulunamadı');
function calistir(anahtar, ...params) {
const islem = islemMap.get(anahtar);
return islem ? islem(...params) : 'Varsayılan işlem';
}
3. Polymorphism (Çok Biçimlilik) ve Strateji Tasarım Deseni
Bu, nesne yönelimli programlamanın gücünü kullanan, ölçeklenebilirlik açısından en güçlü yöntemlerden biridir. Her bir durumu ayrı bir sınıf veya nesne ile temsil ederiz.
- Avantajı: Kod son derece modüler hale gelir. Her bir davranışı bağımsız olarak değiştirebilir, test edebilir ve yeni davranışlar ekleyebilirsiniz. `switch` tamamen ortadan kalkar.
- Dikkat Edilmesi Gereken: Küçük senaryolar için "overkill" (fazla karmaşık) gelebilir.
Kod:
// Her bir ödeme yöntemi için ayrı bir strateji sınıfı
const OdemeStrategileri = {
krediKarti: {
odemeYap: (tutar) => `Kredi kartı ile ${tutar} TL ödendi.`
},
havale: {
odemeYap: (tutar) => `Havale ile ${tutar} TL ödenecek.`
},
kapidaOdeme: {
odemeYap: (tutar) => `Kapıda ${tutar} TL nakit ödeme.`
}
};
class OdemeIslemi {
constructor(stratejiTuru) {
// Strateji nesnesini alıyoruz
this.strateji = OdemeStrategileri[stratejiTuru];
if (!this.strateji) {
throw new Error('Geçersiz ödeme yöntemi');
}
}
odemeYap(tutar) {
return this.strateji.odemeYap(tutar);
}
}
// Kullanımı
const odeme = new OdemeIslemi('kapidaOdeme');
console.log(odeme.odemeYap(150)); // "Kapıda 150 TL nakit ödeme."
4. Fonksiyonların Doğrudan Kullanımı ve Yüksek Mertebeden Fonksiyonlar
Bazen en basit çözüm en iyisidir. Eğer koşullarınız basitse ve her biri bir fonksiyonu tetikliyorsa, bu fonksiyonları doğrudan bir dizide veya başka bir yapıda saklayıp, koşula göre çağırabilirsiniz.
Kod:
const durumlar = [
{ kosul: (user) => user.yas < 18, action: () => 'Giriş Reddedildi' },
{ kosul: (user) => user.yas >= 18 && user.yas < 65, action: () => 'Tam Giriş' },
{ kosul: (user) => user.yas >= 65, action: () => 'Yaşlı İndirimi Uygulandı' },
];
function kullaniciIslemi(user) {
// find metodu ile ilk true olan koşulu bul
const bulunanDurum = durumlar.find(durum => durum.kosul(user));
return bulunanDurum ? bulunanDurum.action() : 'Varsayılan İşlem';
}
5. Dinamik Fonksiyon Çağrıları (Çok Dikkatli Kullanın!)
Bu yöntem biraz daha ileri seviye ve dikkat gerektirir. Fonksiyon isimleriniz, gelen değerle aynı formatta ise, bu fonksiyonları dinamik olarak çağırabilirsiniz. Ancak güvenlik risklerine açıktır, sadece güvendiğiniz, kontrolünüz altındaki verilerle kullanın.
Kod:
class BildirimServisi {
emailGonder() { console.log('Email gönderildi'); }
smsGonder() { console.log('SMS gönderildi'); }
pushGonder() { console.log('Push bildirimi gönderildi'); }
gonder(bildirimTuru) {
const methodName = `${bildirimTuru}Gonder`;
// Metodun var olup olmadığını MUTLAKA kontrol et!
if (typeof this[methodName] === 'function') {
this[methodName]();
} else {
console.log('Geçersiz bildirim türü');
}
}
}
const servis = new BildirimServisi();
servis.gonder('sms'); // "SMS gönderildi"
Sonuç: Doğru Aracı Doğru Yerde Kullanın
- Basit değer döndürme için
Nesne Literali - Kompleks anahtarlar veya sık ekleme/çıkarma için
Map Nesnesi - Büyük ölçekli, bakımı zor sistemler için
Strateji Tasarım Deseni (Polymorphism) - Basit koşul-fonksiyon eşleşmeleri için
Fonksiyon Dizileri - Kontrollü ortamlarda, metod isimleri standart ise
Dinamik Çağrı (nadiren)
Unutmayın, amaç sadece `switch`'ten kurtulmak değil. Amaç daha okunabilir, test edilebilir, sürdürülebilir ve esnek kod yazmaktır.
Umarım bu rehber işinize yarar. Forumda görüşmek üzere, kodunuz temiz, hatasız olsun!
*Bu makaledeki teknikler genellikle "Conditional Logic"ı daha yönetilebilir hale getirmek için kullanılan yaygın pattern'lerdir.*