Giriş
Kodun her yerinde tekrarlanan, anlamı gizli olan sayılar (“magic number”) ve string ifadeler (“magic string”) projenin en büyük bakım kabuslarından biridir.
1. Magic String ve Magic Number Nedir?
-
Magic Number: Kodda açıklamasız ve tekrarlı şekilde kullanılan sayısal değerlerdir.
(ör:if (puan > 85),fiyat = fiyat * 1.18) -
Magic String: Anlamsız, sabit ve tekrar eden string değerlerdir.
(ör:if (user.Role == "Admin"))
Bunlar kodun anlamını gizler, bakımını zorlaştırır ve hata riskini artırır.
2. Neden Kötü Pratik?
- Anlaşılmazlık: Kodun amacı ve mantığı gizlenir.
- Değişiklikte zorluk: Değer birden fazla yerdeyse, güncellemeyi unutmak hata yaratır.
- Hatalı kod tekrarları: Kopyala-yapıştırla çoğalır ve senkronizasyon kaybolur.
- Refactoring ve test zorluğu: Magic değerler unit test veya refactoring’de kolayca gözden kaçar.
3. Magic Kullanımına Kötü (Yanlış) Kod Örnekleri
Magic Number Örneği
double vergi = fiyat * 1.18; // 1.18 nedir?
if (puan > 85) // 85 neyin eşiği?
Console.WriteLine("Geçti");
Magic String Örneği
if (user.Role == "Admin")
Console.WriteLine("Yetkili kullanıcı");
if (status == "Active")
StartService();
4. Alternatifler
1. Const Anahtar Kelimesi
-
Anlamlı isimlendirme, merkezi yönetim
public static class VergiOranlari
{
public const double KDV = 0.18;
}
double vergi = fiyat * (1 + VergiOranlari.KDV);
2. Enum Kullanımı
-
String ve sayı sabitlerini güçlü şekilde yönetir
public enum UserRole { Admin, User, Guest }
if (user.Role == UserRole.Admin)
Console.WriteLine("Yetkili kullanıcı");
3. Static Class ile String Sabitler
public static class StatusCodes
{
public const string Active = "Active";
public const string Passive = "Passive";
}
if (status == StatusCodes.Active)
StartService();
4. Record, Struct veya Value Object
-
Özellikle değer kümesi ve davranış gerekiyorsa
public record Currency(string Symbol, int Precision);
var tl = new Currency("₺", 2);
5. Extension Method ile Yorumlama
-
Magic string/number yerine açıklayıcı fonksiyonlar
public static class UserExtensions
{
public static bool IsAdmin(this User user) => user.Role == UserRole.Admin;
}
if (user.IsAdmin()) { /* ... */ }
6. Configuration/Settings Kullanımı
-
Magic değerleri kod yerine config’e almak
// appsettings.json
{
"SystemSettings": {
"KdvOrani": 0.18,
"AdminRole": "Admin"
}
}
5. Doğru Kullanım Kod Örnekleri
Kötü (Magic Number):
if (puan > 85)
Console.WriteLine("Başarılı!");
İyi (Const ile):
public static class Notlar
{
public const int BasariPuani = 85;
}
if (puan > Notlar.BasariPuani)
Console.WriteLine("Başarılı!");
Kötü (Magic String):
if (user.Status == "Active")
Login();
İyi (Enum ve Static Class ile):
public enum Status { Active, Passive }
if (user.Status == Status.Active)
Login();
veya
public static class UserStatuses
{
public const string Active = "Active";
public const string Passive = "Passive";
}
if (user.Status == UserStatuses.Active)
Login();
6. Avantajlar ve Dezavantajlar
Avantajlar
- Kodun anlamı güçlenir, “neden bu değer var?” sorusunun cevabı görünür.
- Refactoring ve bakım kolaylaşır.
- Hata riski azalır, yanlış değer girme olasılığı yok olur.
- Tek yerden güncelleme imkanı.
Dezavantajlar
- Küçük projede gereksiz complexity yaratabilir.
- Enum/string sabitlerin merkezi yönetimi zaman alabilir.
- Yanlış isimlendirme/organizasyon karmaşaya yol açabilir.
7. Sık Yapılan Hatalar
- Const veya enum yerine string/sayıyı doğrudan yazmak
- Tüm magic değerleri bir dosyada toplamak, mantıksal gruplara ayırmamak
- Enum ve const karışıklığı (ikisini bir arada tutmak)
- Config/constant/enum güncellemesinde değer değişimini kodun her yerine yaymamak
- Magic değerlerin değişebilir (runtime) olmasını unutmak (bazı değerler config olmalı!)
- Anlamsız, kısaltma veya belirsiz isimli sabitler
8. En İyi Uygulamalar ve İpuçları
- Her magic string/number’ı anlamlı bir isme bağla:
AdminRole,KdvOrani,BasariPuanigibi. - Benzer değerleri aynı static class veya enum’da topla.
- Enum’a açıklama (Description) ekle, UI’da göster.
- Sık değişen değerler için config/settings dosyası kullan.
- Public const/enum değerlerini sadece ihtiyaç olan katmana aç.
- Unit testlerde magic değer değil, sabitleri kullan.
- Extension method ile kodu daha okunur ve anlamlı hale getir.
9. Tablo & Diyagram
Kötü (Magic) ve İyi (Alternatif) Kullanım Tablosu
| Magic Kullanım | Alternatif |
|---|---|
"Admin" |
UserRoles.Admin |
puan > 85 |
puan > Notlar.BasariPuani |
"Active" |
StatusCodes.Active / enum Status.Active |
fiyat * 1.18 |
fiyat * (1 + VergiOranlari.KDV) |
10. SSS – Sıkça Sorulan Sorular
Enum mu, const mu?
Sayı veya string koleksiyonuysa enum; gerçek sabitse const tercih edilir.
Magic değerler küçük projede de risk mi?
Evet, özellikle kod büyüyüp değiştikçe risk artar.
Enum’ların string değeri nasıl alınır?
Enum’a [Description] ekleyerek extension ile string’e çevirebilirsin.
Magic değerler her zaman config’te mi olmalı?
Sık değişen (deployment bağımlı) değerler config’te, sabit olanlar kodda const/enum olmalı.
Birden fazla magic value için nasıl yönetim?
Mantıksal olarak gruplandır (örn: UserRoles, StatusCodes).
11. Sonuç ve Pratik Özet
- Magic string/number’ları doğrudan kodda kullanmak bakımı zorlaştırır, hata riskini artırır.
- Const, enum, static class, extension method ve config/settings ile kodun anlamı güçlenir.
- Her değer bir isme, her isim bir amaca sahip olmalı.
- Özellikle ekip çalışmalarında, merkezi sabit yönetimi büyük avantaj sağlar.
- Modern C# projelerinde magic string/number’ı sıfıra indirmek mümkündür.