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, BasariPuani gibi.
  • 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.

12. Kaynaklar

By tanju.bozok

Software Architect, Developer, and Entrepreneur

Bir yanıt yazın

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