Altbilgi içeriğine atla
Iron Academy Logo
C# Yaygın Sorunlar

C#'ta Koşullu if Yeniden Düzenleme: Derek Comartin ile Koşullu Karmaşadan Kaçınma

[[academy-video-youtube({"vid": "QoK7jSZ-viw", "start_time": "0", "title": "Enums aren't evil. Conditionals everywhere are", "creator": "Derek Comartin", "length": "11m 03s"})]]

C#'ta, if ifadesi, if: else ifadesi ve switch ifadesi gibi koşullu ifadeler önemli araçlardır. Ancak bu yapılar aşırı kullanıldığında, özellikle enuma bağlı olarak, ne olur? Derek Comartin, Enums Kötü Değil. Heryerde Koşullar Kötü videosunda, kapsamlı bir yeniden düzenlemeyle yaygın koşullu mantığı daha temiz, daha sürdürülebilir desenlerle değiştiren bir kılavuz sunar.

Bu makalede, Derek'in açıklamalarını onun zaman damgalarını başvuru noktaları olarak kullanarak adım adım ele alacağız. Aynı zamanda, bu fikirlerin C#'ta yaygın koşullu desenlere nasıl uygulandığını da keşfedeceğiz; ternary operatörü, else ifadesi ve switch-case yapıları gibi — büyük kod tabanlarında sorunlar çıkarabileceği yerleri ve tasarımı iyileştirmeye yönelik nasıl bir yöntemle yeniden düzenlenebileceğini inceleyerek.

Koşullu If Patlaması: Asıl Problem

Derek, ürün türünü kontrol eden bir if ifadesini göstererek başlar.

if (productType == ProductType.Template || productType == ProductType.Ebook)
if (productType == ProductType.Template || productType == ProductType.Ebook)

İlk bakışta, yukarıdaki koşullu if ifadesi basit görünüyor. Ancak Derek, bu tür ifadelerin belirli bir koşulu değerlendirdiğini ve koşul doğruysa yalnızca bir kod bloğunun çalıştırıldığını, bu mantık tekrar edildiğinde sorunlu hale geldiğini belirtiyor.

Bu bloğu başka bir yöntem veya sınıfta tekrar kullanabilirsiniz:

if (offeringType == ProductType.Template || offeringType == ProductType.Ebook)
if (offeringType == ProductType.Template || offeringType == ProductType.Ebook)

Derek, bu kalıbın hızla büyük bir sistemde yayılabileceğini açıklıyor. Aynı if else mantığı birden fazla hizmette belirir, yeni bir enum değeri eklerken tutarsızlıklar ve hatalar oluşur. Örneğin, Video gibi yeni bir ürün türü tanıttığınızda ne olur? Bu koşullu ifadenin bulunduğu her bloğu güncellemeniz gerekecek.

Tekrar Karmaşıklığı Artırır

Aşağıdaki örnekte, Derek iç içe geçmiş koşullara derinlemesine bakıyor. Bir yöntemin içinde, bir if else ifadesi aynı enum'u kontrol eder ve bu sonuç başka bir yönteme iletilir, bu da benzer bir kontrol içerir.

İfade, Şablon veya E-kitap için kontrol yapar ve bir şey döndürür, aksi takdirde null döndürür. Derek, bu türden bir fazlalığın yalnızca kodu uzatmadığını, bakım tehlikeleri de oluşturduğunu belirtiyor. Aynı mantık birden fazla dosyada kopyalanır, kontrol akışının kaosa dönüşmesine neden olur.

Eğer sisteminiz her enum'a dokunduğunuzda bir varsayılan durum eklemenizi gerektiriyorsa, bir şeylerin ters gittiğini bilirsiniz.

Koşullara Dair Düşünme Şeklimizi Değiştirmek

Sürekli olarak if else ile türleri kontrol etmek yerine, Derek daha iyi bir soru sormayı öneriyor:

Ürünün indirilebilir özellikleri var mı?

Bu, niyeti daha iyi ifade eder. Kodunuzu daha okunabilir hale getirir ve tamamen enum'a bağımlılığı azaltır. İki koşullu bir if ifadesi yazmak yerine:

if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)
if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)

Bu mantığı bir modelde kapsüllendirip şöyle yazabilirsiniz:

if (product.HasDownloadableResource())
if (product.HasDownloadableResource())

Bu, yalnızca indirilebilir bir kaynak mevcut olduğunda true döner ve karmaşık koşullu ifadelere olan ihtiyacı azaltır.

If İfadelerinden Kapsüllendirilmiş Davranaşlara

Temel sorunu çözmek için, Derek bir DownloadableResource türü tanıtır. Bu tür, bir indirme URL'si ve varsayılan bir dosya adını içerir. Bu, if ifadelerine güvenmek yerine, alanınızın birinci sınıf bir parçası haline gelir.

Artık bunu sürekli tekrar etmek yerine:

if (product.Type == ProductType.Template)
{
    // Generate file name
}
else if (product.Type == ProductType.Ebook)
{
    // Generate file name
}
if (product.Type == ProductType.Template)
{
    // Generate file name
}
else if (product.Type == ProductType.Ebook)
{
    // Generate file name
}

Bunu yazarsınız:

var downloadable = product.GetDownloadableResource();
if (downloadable != null)
{
    Console.WriteLine(downloadable.FileName);
}
var downloadable = product.GetDownloadableResource();
if (downloadable != null)
{
    Console.WriteLine(downloadable.FileName);
}

Bu, mantığı büyük ölçüde basitleştirir ve else ifade dallarına veya hatta bir switch ifadesine gerek kalmaz.

Derleme Zamanından Çalışma Zamanına: Stratejik Bir Değişim

Derek, mantığın derleme zamanından çalışma zamanına kaydırıldığı önemli bir tasarım tercihini açıklayarak daha da ileri gider. Bu, bir ürün için bir DownloadableResource var olup olmadığını görmek için sistemi çalışma zamanında sorgulamak demektir. Eğer varsa, üzerine hareket edin. Eğer yoksa, geçin.

Bu adımın, if else mantığını statik olmaktan çıkarıp çalışma zamanında sorguya dönüştürdüğünü belirtiyor. Bir veri tabanı çağrısı ekleyebilir, ancak iç içe geçmiş if else mantığını azaltır ve davranışı merkezileştirir. Bu, büyük çapta sürdürülebilirliği artırır.

İndirilebilir Ürünler için Kalıtım Kullanımı

Derek'in keşfettiği bir diğer yol kalıtımdır. Soyut bir temel sınıf Ürün oluşturabilir ve ardından türetilmiş türleri tanımlayabilirsiniz, örneğin Ebook, Şablon veya OfflineCourse.

Her biri şu türden yöntemleri geçersiz kılar:

public virtual string GetDownloadUrl() { ... }
public virtual string GetDownloadUrl() { ... }

Bu yaklaşım, her ürünün kendi mantığını yönetmesine olanak tanır. Bu, bir switch ifadesini veya birden fazla koşullu ifadeyi önlerken, dikkatli olunmazsa yine de içsel koşullu ifadeler yazılabileceğini belirtir.

Kalıtım Olmadan Daha İyi Kapsülleme

Eğer kalıtım aşırı yük gibi geliyorsa, Derek, hiyerarşiye bağlı olmadan kendi özelliklerini ve yöntemlerini içeren DownloadableProduct gibi açık türler kullanmayı önerir.

Programınızda bu şu şekilde görünebilir:

var downloader = new DownloadableProduct(product);
Console.WriteLine(downloader.GetDefaultFileName());
var downloader = new DownloadableProduct(product);
Console.WriteLine(downloader.GetDefaultFileName());

Davranışı belirlemek için bir if else veya switch ifadesine gerek yoktur - her nesne ne yapacağını bilir.

Hafif Çözüm: Enumlar Üzerinde Uzatma Yöntemleri

Enumlardan vazgeçmeye hazır değilseniz, Derek hafif bir çözüm öneriyor - bir uzatma yöntemi oluşturun:

public static bool IsDownloadable(this ProductType type)
{
    return type == ProductType.Template || type == ProductType.Ebook;
}
public static bool IsDownloadable(this ProductType type)
{
    return type == ProductType.Template || type == ProductType.Ebook;
}

Şimdi bunun yerine:

if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)
if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)

Bunun yerine şunu yazabilirsiniz:

if (product.Type.IsDownloadable())
if (product.Type.IsDownloadable())

Bu, mantığınızı merkezileştirir ve süslü parantezleri ve kod bloğunun sürekli tekrarını önler.

Artımsal Operatör ve Switch Kullanmaktan Kaçının

Derek, artımsal operatör gibi kısayolları aşırı kullanmaktan da uyarıyor:

string filename = product.Type == ProductType.Template ? "template.pdf" : "default.pdf";
string filename = product.Type == ProductType.Template ? "template.pdf" : "default.pdf";

Bu geçerli bir sözdizimi olsa da, mantık karmaşıklaştığında hataya meyilli ve zor okunabilir olabilir. Özellikle koşulunuz yanlış olarak değerlendirilirse, yanlış değer ince yollarla atanabilir.

Benzer şekilde, bir break ifadesi ve varsayılan durumu olan switch ifadesi de bu tuzağa düşer. Objelere davranışlarını sormak switch-case mantığı kullanmaktan daha iyidir.

Sonuç: Daha Az Koşullu Karmaşayla Daha Akıllıca Kontrol

Sonuç olarak, Derek'in videosu enumlara bir saldırı değil, etrafında kullandığımız koşullu if yapılarını eleştiren bir çalışmadır. Eğer if else ve switch ifadelerini kod tabanınıza yayarsanız, sistemi test etmeyi, sürdürmeyi ve geliştirmeyi zorlaştırırsınız.

Kapsülleme, çalışma zamanı sorgulaması, kalıtım veya basit uzatma yöntemlerinden hangisini seçerseniz seçin, amaç aynı kalır: koşulları azaltın ve mantığı yerine taşıyın.

Unutmayın:

  • Koşullar kötü değildir.

  • Koşullu düzensizlik kötüdür.

  • Temiz kod, sınıflar arasında yayılmış birden fazla if else ifadesine güvenmez.

  • Bağlamınızı değerlendirin ve buna göre düzenleyin.

Derek'in dediği gibi, "Bağlamınıza bağlı." Ama bir şey kesin: bir ürün her zaman sadece bir ürün değildir - bazen tasarımınızı yeniden düşünmeniz için bir işarettir.

Hero Worlddot related to C#'ta Koşullu if Yeniden Düzenleme: Derek Comartin ile Koşullu Karmaşadan Kaçınma
Hero Affiliate related to C#'ta Koşullu if Yeniden Düzenleme: Derek Comartin ile Koşullu Karmaşadan Kaçınma

Sevdiğiniz Şeyleri Paylaşarak Daha Fazla Kazanın

.NET, C#, Java, Python veya Node.js ile çalışan geliştiriciler için içerik oluşturuyor musunuz? Uzmanlığınızı ek gelire dönüştürün!

Iron Destek Ekibi

Haftada 5 gün, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara