Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Derek Comartin
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.
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 OrElse productType = ProductType.Ebook Thenİ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 OrElse offeringType = ProductType.Ebook ThenDerek, 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.
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.
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 OrElse product.Type = ProductType.Ebook ThenBu mantığı bir modelde kapsüllendirip şöyle yazabilirsiniz:
if (product.HasDownloadableResource())If product.HasDownloadableResource() ThenBu, yalnızca indirilebilir bir kaynak mevcut olduğunda true döner ve karmaşık koşullu ifadelere olan ihtiyacı azaltır.
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 Then
' Generate file name
ElseIf product.Type = ProductType.Ebook Then
' Generate file name
End IfBunu yazarsınız:
var downloadable = product.GetDownloadableResource();
if (downloadable != null)
{
Console.WriteLine(downloadable.FileName);
}Dim downloadable = product.GetDownloadableResource()
If downloadable IsNot Nothing Then
Console.WriteLine(downloadable.FileName)
End IfBu, mantığı büyük ölçüde basitleştirir ve else ifade dallarına veya hatta bir switch ifadesine gerek kalmaz.
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.
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 Overridable Function GetDownloadUrl() As String
' ...
End FunctionBu 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.
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());Dim 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.
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 Shared Function IsDownloadable(type As ProductType) As Boolean
Return type = ProductType.Template OrElse type = ProductType.Ebook
End FunctionŞimdi bunun yerine:
if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)If product.Type = ProductType.Template OrElse product.Type = ProductType.Ebook ThenBunun yerine şunu yazabilirsiniz:
if (product.Type.IsDownloadable())If product.Type.IsDownloadable() ThenBu, mantığınızı merkezileştirir ve süslü parantezleri ve kod bloğunun sürekli tekrarını önler.
Derek, artımsal operatör gibi kısayolları aşırı kullanmaktan da uyarıyor:
string filename = product.Type == ProductType.Template ? "template.pdf" : "default.pdf";Dim filename As String = If(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ç 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.
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy