Strategy Kalıbı
Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 55 / 70.
Strategy pattern, bir algoritma ailesi tanımlamanıza, her birini kendi sınıfında kapsüllemenize ve çalışma zamanında birbirleriyle değiştirilebilir hâle getirmenize olanak tanıyan davranışsal bir kalıptır. Davranışı sabit kodlamak yerine, istediğiniz stratejiyi bir nesneye enjekte edersiniz.
Örüntü üç bölümden oluşur: algoritma sözleşmesini tanımlayan bir strateji arabirimi, farklı davranışları uygulayan somut strateji sınıfları ve bir strateji kullanan bir bağlam sınıfı:
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
public class CreditCardPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via Credit Card");
}
public class PayPalPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via PayPal");
}
public class ShoppingCart
{
private IPaymentStrategy _paymentStrategy;
public void SetPaymentMethod(IPaymentStrategy strategy)
{
_paymentStrategy = strategy;
}
public void Checkout(decimal total)
{
_paymentStrategy.Pay(total);
}
}Bağlam (ShoppingCart) hangi ödeme yöntemini kullandığını bilmez; yalnızca sağlanan herhangi bir strateji üzerinde Pay() çağrısı yapar:
var cart = new ShoppingCart();
cart.SetPaymentMethod(new CreditCardPayment());
cart.Checkout(99.99m); // 99.99 Kredi Kartı ile ödendi
cart.SetPaymentMethod(new PayPalPayment());
cart.Checkout(49.99m); // 49.99 PayPal ile ödendiStrategy kalıbı, karmaşık koşullu mantığı ortadan kaldırır. Yeni bir ödeme yöntemi eklemek, IPaymentStrategy uygulayan yeni bir sınıf oluşturmak anlamına gelir; ShoppingCart içinde hiçbir değişiklik yapılması gerekmez. Bu, kodunuzu genişletmeye açık, ancak değişikliğe kapalı hâle getirir.
Görev
KolayStrategy desenini kullanarak bir kargo ücreti hesaplayıcısı oluşturalım. Farklı kargo yöntemlerinin farklı fiyatlandırma algoritmaları vardır ve sisteminiz, temel sipariş işleme mantığını değiştirmeden bunlar arasında çalışma zamanında geçiş yapmaya izin vermelidir.
Kodunuzu üç dosya arasında düzenleyeceksiniz:
ShippingStrategy.cs:Shippingad alanında birIShippingStrategyarayüzü tanımlayın. Bu arayüz,doubledöndürenCalculateCost(double weight)metoduna sahip olmalıdır. Ardından üç somut strateji sınıfı oluşturun:StandardShipping- ücretiweight * 1.5olarak hesaplarExpressShipping- ücretiweight * 3.0 + 5.0olarak hesaplar (sabit ekspres ücretini içerir)OvernightShipping- ücretiweight * 5.0 + 10.0olarak hesaplar (daha yüksek temel ücrete sahip premium hizmet)
OrderProcessor.cs: Aynı ad alanında birOrderProcessorsınıfı oluşturun. Bu, bir kargo stratejisi kullanan bağlam sınıfınızdır. Şunlara sahip olmalıdır:- Geçerli
IShippingStrategy'yi tutan özel bir alan - Kargo stratejisini değiştirmek için bir
SetShippingMethod(IShippingStrategy strategy)metodu - Geçerli stratejiyi kullanarak kargo ücretini hesaplayıp döndüren bir
ProcessOrder(double weight)metodu
- Geçerli
Program.cs: BirOrderProcessoroluşturarak ve kargo stratejilerini çalışma zamanında nasıl değiştirebileceğinizi göstererek her şeyi bir araya getirin. Aynı işlemci, yalnızca stratejisini değiştirerek farklı algoritmaları kullanarak ücretleri hesaplayabilir.
İki girdi alacaksınız:
- Kargo yöntemi türü:
standard,expressveyaovernight - Ondalık sayı olarak paket ağırlığı (örneğin,
4.5)
Bir OrderProcessor oluşturun, girdi türüne göre uygun kargo stratejisini ayarlayın, ardından siparişi işleyip hesaplanan ücreti yazdırın.
Örneğin girdiler express ve 4.5 ise çıktı şu şekilde olmalıdır:
18.5Bu, Strategy deseninin gücünü gösterir - OrderProcessor herhangi bir kargo hesaplama mantığı içermez. İşlemciye verilen stratejiye basitçe yetki devreder; bu da işlemcide hiçbir değişiklik yapmadan yeni kargo yöntemleri (örneğin DroneDelivery) eklemeyi kolaylaştırır!
Kendin dene
using System;
using Shipping;
class Program
{
public static void Main(string[] args)
{
// Girişi oku
string shippingType = Console.ReadLine();
double weight = Convert.ToDouble(Console.ReadLine());
// TODO: Bir OrderProcessor örneği oluştur
// TODO: shippingType'a göre ("standard", "express" veya "overnight"),
// uygun gönderim stratejisini oluştur ve işlemciye ayarla
// TODO: Siparişi işle ve hesaplanan maliyeti yazdır
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci KayıtlarıKendi başına pratik yap: Online C# derleyicisi