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
8m 44s
C# programlama dili alanında, çift geçiş sıklıkla yanlış anlaşılan veya az kullanılan bir tekniktir. Özellikle türetilmiş sınıflar arasındaki davranışları işlerken, iki nesne arasında çok biçimli davranış sağlayan güçlü bir tekniktir.
"Çift Geçiş DDD'de: Bağımlılık Enjeksiyonu Ne Zaman Anlamlıdır" adlı videosunda, Derek Comartin çift geçişin Alan-Yönlendirmeli Tasarım (DDD) ile nasıl mükemmel uyum sağladığını ele alıyor. Bakım yükünü nasıl azaltabileceğini, mevcut kodu nasıl sadeleştirebileceğini ve hatta diğer dillerde yaygın olarak görülen ziyaretçi deseni gibi desenleri nasıl taklit edebileceğini gösteren örneklerini derinlemesine inceleyeceğiz.
C#'ta tekli geçişin kısıtlamalarıyla uğraştıysanız veya hem bir nesne örneği hem de enjekte edilen bir strateji veya kurala dayalı davranış belirlemeye çalıştıysanız, bu makale C#'ta çift geçişin nasıl etkili bir şekilde kullanılabileceğini daha iyi anlamanıza yardımcı olacak.
Derek, DDD'de yaygın bir dogma ile başlar: alan modelinizin sıfır bağımlılığı olması gerektiği. Ancak bu her zaman pratik veya kullanışlı değildir. Davranışı modellerken, kurallar, politikalar veya stratejiler gibi mantığı enjekte etmeniz gerekebilir. İşte burada çift geçiş yardımcı olur: Bir politika gibi bir alan konseptini alan nesneye geçirebilir ve metod tabanlı değerlendirme harici olarak ele alınabilir—ancak alan nesnesi hala son kontrolü elinde tutabilir.
Bu desen, neye bağlandığınızı düşündüğünüzde mantıklıdır: alan davranışına, altyapıya değil.
Sorunu göstermek için Derek, gecikmeyi belirlemek için kodlu bir mantık içeren bir Gönderi sınıfıyla başlar:
public bool IsLate(DateTime expectedDelivery)
{
return _systemClock.Now() > expectedDelivery;
}Public Function IsLate(expectedDelivery As DateTime) As Boolean
Return _systemClock.Now() > expectedDelivery
End FunctionBu mevcut kod basit ama esneklikten yoksun. Derleme zamanındaki kararlara dayanır ve davranışı sınıfa sıkı sıkıya bağlar. Kuralı değiştirmek, alan modelini değiştirmeyi gerektirir ve testi zorlaştırır çünkü zaman bağlıdır.
Derek, IDeliveryTimingPolicy arayüzünü tanıtır:
public interface IDeliveryTimingPolicy
{
bool IsLate(Shipment shipment);
}Public Interface IDeliveryTimingPolicy
Function IsLate(shipment As Shipment) As Boolean
End InterfaceArdından iki uygulama oluşturur:
StandartTeslimatZamanlamaPolitikası
AraBellekTeslimatZamanlamaPolitikası
Bu sınıflar Gönderiyi alır ve kurallarına göre bir boole döndürür. İşte BufferedDeliveryTimingPolicy'den bir kod parçası:
public bool IsLate(Shipment shipment)
{
return _clock.Now() > shipment.DeliveryDate.AddMinutes(30);
}Public Function IsLate(shipment As Shipment) As Boolean
Return _clock.Now() > shipment.DeliveryDate.AddMinutes(30)
End FunctionŞimdi Gönderi sınıfında, çift geçiş kullanıyoruz.
public bool IsLate(IDeliveryTimingPolicy policy)
{
return policy.IsLate(this);
}Public Function IsLate(ByVal policy As IDeliveryTimingPolicy) As Boolean
Return policy.IsLate(Me)
End FunctionBu, klasik çift geçiştir: ilk geçiş, politikayı gönderipemme üzerine IsLate() çağrısı yapar; ikinci geçiş, gönderiyi bir parametre olarak politika ile IsLate() çağrısı yapar. İki nesne yer alır, her biri davranışı belirler—tekli geçişin ulaşamadığı bir şey.
Bu yaklaşım son derece test edilebilir ve deterministik kod ile sonuçlanır. Derek, test verilerin kontrol edildiği ve her nesnenin çalışma zamanı türünün davranışı belirlediği standart ve buffer politikalarını kullanan örnekler gösterir.
var policy = new BufferedDeliveryTimingPolicy(TimeSpan.FromMinutes(30));
var shipment = new Shipment { DeliveryDate = DateTime.UtcNow.AddMinutes(-15) };
Assert.False(shipment.IsLate(policy)); // Because of 30-minute bufferDim policy = New BufferedDeliveryTimingPolicy(TimeSpan.FromMinutes(30))
Dim shipment = New Shipment With {.DeliveryDate = DateTime.UtcNow.AddMinutes(-15)}
Assert.False(shipment.IsLate(policy)) ' Because of 30-minute bufferBu, çalışma zamanı davranışının alan modelini değiştirmeden değiştirilebileceğini gösterir. Polimorfik davranış, politikanın dinamik doğasına dayanır, alan bütünlüğü korunurken.
Derek'in örneği ziyaretçi desenine benzer, burada yapılarını değiştirmeden nesneler üzerinde bir dizi işlem tanımlarsınız. Genellikle ziyaretçi deseninde, şöyle bir şey görürsünüz:
public abstract class Shape
{
public abstract void Accept(IVisitor visitor);
}
public class Circle : Shape
{
public override void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}Public MustInherit Class Shape
Public MustOverride Sub Accept(visitor As IVisitor)
End Class
Public Class Circle
Inherits Shape
Public Overrides Sub Accept(visitor As IVisitor)
visitor.Visit(Me)
End Sub
End ClassBurada, Accept() ve Visit() yöntemleri, nesne ve ziyaretçi olmak üzere iki tür arasında koordine edilir—tıpkı Derek'in Gönderi ve IDeliveryTimingPolicy kullanımı gibi. Bu desen, tekli geçiş dili olan C#'ta bile çoklu geçiş davranışını uygulamanıza yardımcı olur.
Bir sonraki örnekte, Derek bir koleksiyon üzerinden birden fazla kuralın nasıl değerlendirilebileceğini gösterir. Kurallar gibi tanıtır:
Geçerli Hedef Kuralları Var
Tüm Paketler Paketlenmiş Kuralı
Daha Önce Gönderilmemiş Kuralı
Her biri IShipmentReadinessRule ile uygular:
public bool IsSatisfiedBy(Shipment shipment)Public Function IsSatisfiedBy(shipment As Shipment) As BooleanSonra, Gönderi sınıfı onları şöyle değerlendirir:
public bool CanShip(IEnumerable<IShipmentReadinessRule> rules)
{
return rules.All(rule => rule.IsSatisfiedBy(this));
}Public Function CanShip(rules As IEnumerable(Of IShipmentReadinessRule)) As Boolean
Return rules.All(Function(rule) rule.IsSatisfiedBy(Me))
End FunctionBu boş kabul deseni, çoklu alan kurallarını dinamik olarak değerlendirebilmenizi sağlar. Kuralları bir konfigürasyonda saklarsanız (özellikle çoklu kiracı bir uygulamada), çalışma zamanında yeni bir liste oluşturabilir ve gönderiye geçebilirsiniz.
Derek, çoklu kiracı uygulamalarda kuralların müşteri başına değişebileceğini vurguluyor. Depolamadan bir dizi politika alabilir ve onları dinamik olarak enjekte edebilirsiniz:
var rules = LoadRulesForCustomer(customerId);
var canShip = shipment.CanShip(rules);Dim rules = LoadRulesForCustomer(customerId)
Dim canShip = shipment.CanShip(rules)Bu, dinamik gönderim ve çalışma zamanı karar alma yeteneğinin uygulamanıza nasıl katmanıza yardımcı olabileceğini gösterir. İstenen davranış konfigürasyonu değiştirerek elde edilir, modeli değil.
Sonlara doğru, Derek herhangi bir şeyin alana enjekte edilmesinin kötü olduğuna dair yanlış anlamaları ele alır. Önemli olanın neyi enjekte ettiğiniz olduğunu vurgular. Alan davranışı, spesifikasyonlar veya politikalar gibi şeylerin enjeksiyonu, altyapı enjeksiyonu ile aynı şey değildir.
Alan modeli giriş noktası olarak kalır. Kararı sahiplenir ancak hala alan bağlamı içinde kaldıkları sürece diğer nesnelere bu kararı devredebilir.
Derek, kritik düşünmeye teşvik ederek bitirir: asla boş ziyaret, genel sanal boş kabul veya benzeri desenlerden korkmayın çünkü bunlar netlik ve sürdürülebilirliğe katkıda bulunurlar. İşletim mantığını kontrollü bir şekilde enjekte ettiğinizde, esneklik ve hassasiyet kazanırsınız.
Bu yüzden, ister yeni bir sınıf üzerinde çalışıyor olun, ister mevcut bir kod tabanını refaktör ediyorsanız, çift geçiş C#'ı, endişeleri ayırmak ve alan odaklılığını korumak için temiz bir yol sunar.
Politikaları veya spesifikasyonları kullanıyorsanız veya farkında olmadan bir ziyaretçi deseni olabilirsiniz, siz zaten çift geçişi uygulamaya oldukça yakınsınız. Bunu anlamak, çalışma zamanında kodun nasıl davrandığı üzerinde daha fazla kontrol sağlar, test edilebilirliği ve adaptasyonu geliştirmektedir.
Özetlemek gerekirse: çift geçiş C#'da, alan mantığını enjekte etmek için zarif ve pratik bir çözüm olabilir, kapsüllemeyi korur ve esnek davranışı destekler. Ziyaretçi, çoklu geçiş ve dinamik anahtar kelime kullanımı gibi desenlerle birlikte kullanıldığında (dikkatle), ifadeli, sağlam alan modelleri yazmayı kolaylaştırır.
Bu yüzden bir sonraki sefer gönderi.IsLate(policy) çağırdığınızda—bilin ki C#'ı gerçekten polimorfik tasarıma yaklaştıran temel bir deseni kullanıyorsunuz.
Örnek İpucu: Satın Alma Siparişi sınıfı oluşturuyorsanız ve bir kulanın bir Politika'ya göre eklenip eklenmeyeceğini belirlemek istiyorsanız, politikayı Satın Alma Siparişi'ne geçirmeyi deneyin ve Politika'nın siparişi ziyaret etmesine izin verin. İşte çift geçiş çalışması.
Tam videoyu onun YouTube kanalında izleyin ve konu üzerinde daha fazla bilgi edinin.
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