Strategy Deseni
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 74 / 91.
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 tasarım desenidir. Stratejiyi kullanan nesnenin hangi algoritmayı çalıştırdığını bilmesi gerekmez.
Farklı indirim stratejileri uygulayabilen bir alışveriş sepeti hayal edin. İndirim mantığını koşullu ifadelerle sabit kodlamak yerine, her indirimi ayrı bir sınıf olarak tanımlarsınız:
<?php
interface DiscountStrategy {
public function calculate(float $total): float;
}
class NoDiscount implements DiscountStrategy {
public function calculate(float $total): float {
return $total;
}
}
class PercentageDiscount implements DiscountStrategy {
public function __construct(private int $percent) {}
public function calculate(float $total): float {
return $total - ($total * $this->percent / 100);
}
}
class FixedDiscount implements DiscountStrategy {
public function __construct(private float $amount) {}
public function calculate(float $total): float {
return max(0, $total - $this->amount);
}
}
Bağlam sınıfı herhangi bir stratejiyi kabul eder ve hesaplamayı devreder:
<?php
class ShoppingCart {
public function __construct(private DiscountStrategy $discount) {}
public function setDiscount(DiscountStrategy $discount): void {
$this->discount = $discount;
}
public function checkout(float $total): float {
return $this->discount->calculate($total);
}
}
$cart = new ShoppingCart(new NoDiscount());
echo $cart->checkout(100) . "\n";
$cart->setDiscount(new PercentageDiscount(20));
echo $cart->checkout(100);
Çıktı:
100
80Strategy Pattern, bir işlemi gerçekleştirmenin birden çok yoluna sahip olduğunuzda ve bunlar arasında, bunları kullanan sınıfı değiştirmeden geçiş yapmak istediğinizde öne çıkar. Yeni bir indirim türü eklemek, mevcut koda dokunmak yerine yeni bir sınıf oluşturmak anlamına gelir.
Görev
KolayStrategy Pattern'ı kullanarak bir kargo ücreti hesaplayıcısı oluşturalım. Farklı kargo yöntemlerinin farklı fiyatlandırma kuralları vardır: standart kargo sabit bir ücret alır, ekspres kargo bir yüzde ekler ve gece kargosu her ikisini birleştirir. Strategy Pattern, hesaplamaları kullanan kodu değiştirmeden bu hesaplamalar arasında geçiş yapmanızı sağlar.
Kodunuzu dört dosyaya ayıracaksınız:
ShippingStrategy.php: Tüm kargo yöntemleri için sözleşmeyi tanımlayan birShippingStrategyarayüzü oluşturun. Bu arayüz, paket ağırlığını alan ve kargo ücretini döndürencalculate(float $weight): floatmetoduna sahip olmalıdır.ShippingMethods.php: ShippingStrategy dosyasını dahil edin ve arayüzü uygulayan üç sınıf oluşturun:StandardShipping: Ağırlıktan bağımsız olarak$5.00sabit ücret alırExpressShipping: Kilogram başına$2.00ücret alır (ağırlığı 2 ile çarpın)OvernightShipping:$10.00temel ücretin yanı sıra kilogram başına$3.00ücret alır
ShippingCalculator.php: ShippingStrategy dosyasını dahil edin ve bağlam görevi gören birShippingCalculatorsınıfı oluşturun. Hesaplayıcınız:- Yapıcısında bir
ShippingStrategykabul etmelidir (yapıcı tanıtımını kullanın) - Çalışma zamanında kargo yöntemini değiştirmek için
setStrategy(ShippingStrategy $strategy): voidmetoduna sahip olmalıdır - Geçerli stratejiye yetki devreden bir
calculateCost(float $weight): floatmetoduna sahip olmalıdır
- Yapıcısında bir
main.php: ShippingMethods ve ShippingCalculator dosyalarını dahil edin. İki girdi alacaksınız: bir kargo türü ("standard","express"veya"overnight") ve bir paket ağırlığı.StandardShippingile başlayan birShippingCalculatoroluşturun. Kargo türü girdisine göre uygun kargo yöntemine geçmek içinsetStrategy()kullanın. Ardından verilen ağırlık için ücreti hesaplayın ve sonucu iki ondalık basamakla biçimlendirilmiş olarak yazdırın.Çıktı şu şekilde olmalıdır:
Shipping cost: $[cost]
Bu görev, Strategy Pattern'ın kargo sisteminizi nasıl esnek hâle getirdiğini gösterir: SameDayShipping gibi yeni bir kargo yöntemi eklemek, hesaplayıcıya veya mevcut kargo yöntemlerine dokunmadan yalnızca arayüzü uygulayan yeni bir sınıf oluşturmayı gerektirir.
Kendin dene
<?php
require_once 'ShippingMethods.php';
require_once 'ShippingCalculator.php';
// Girişi oku
$shippingType = trim(fgets(STDIN));
$weight = floatval(fgets(STDIN));
// TODO: StandardShipping ile başlayan bir ShippingCalculator oluştur
// TODO: Gönderim türü girdisine göre ("standard", "express" veya "overnight"),
// uygun gönderim yöntemine geçmek için setStrategy() kullan
// TODO: Verilen ağırlık için maliyeti hesapla
// TODO: Sonucu iki ondalık basamağa biçimlendirilmiş olarak yazdır
// Output format: Shipping cost: $[cost]
?>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 DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar SözcüğüMetotlarÖzelliklerYapıcı (__construct)Yıkıcı (__destruct)Tekrar - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar SözcüğüMetot Geçersiz Kılmafinal Anahtar SözcüğüSoyut SınıflarTekrar - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicileri DerinlemesineGetter ve Setter'larBilgi GizlemeYapıcı Özellik Terfisi (8.0)Tekrar - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Composition ve KalıtımBağımlılık EnjeksiyonuAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlamaya Derinlemesine BakışÜreteçler ve Yineleyiciler13Tasarı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ıBileşik KalıpDepo Kalıbı2Namespace’ler ve Autoloading
Namespace’lere Girişuse Anahtar SözcüğüPSR-4 Autoloading StandardıComposer AutoloaderTekrar - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Çok Arayüz UygulamaArayüz ve Soyut Sınıf KarşılaştırmasıArayüzlerle Tür İpuçlarıTekrar - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString ve __debugInfo__get, __set, __isset, __unset__call ve __callStatic__clone ve Nesne Klonlama__serialize ve __unserializeTekrar - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerSalt Okunur Özellikler (PHP 8.1)Tekrar - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmayı Yeniden Ele AlmaArayüzler Yoluyla Çok BiçimlilikTür İpuçları ve Birleşim TürleriGeç Bağlanan Statik ÇağrılarÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişBirden Çok Trait KullanımıTrait Çakışmalarını ÇözümlemeTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım Karşılaştırması12Tasarım Desenleri 1. Bölüm
Tasarım Desenlerine GirişSingleton DeseniFactory DeseniObserver DeseniStrategy DeseniKendi başına pratik yap: Online PHP derleyicisi