Strateji Kalıbı
Coddy'nin Swift Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 45 / 57.
strategy kalıbı, bir algoritmanın her varyantını ortak bir protokolün arkasında kendi türüne yerleştirir. Bu kalıbı kullanan kod bir strateji tutar ve çalışma zamanında bunu değiştirebilir:
protocol ShippingStrategy {
func cost(weight: Int) -> Int
}
struct Standard: ShippingStrategy { func cost(weight: Int) -> Int { 5 + weight } }
struct Express: ShippingStrategy { func cost(weight: Int) -> Int { 15 + weight * 2 } }
struct Checkout {
var shipping: any ShippingStrategy
func total(price: Int, weight: Int) -> Int { price + shipping.cost(weight: weight) }
}
var c = Checkout(shipping: Standard())
print(c.total(price: 100, weight: 3))
c.shipping = Express()
print(c.total(price: 100, weight: 3))Çıktı:
108
121Swift'te, tek metotlu bir strateji için çoğu zaman bir closure yeterlidir. Tür, bir işlev depolar ve onu çağırır:
struct Sorter {
var rule: (String, String) -> Bool
func sort(_ words: [String]) -> [String] { words.sorted(by: rule) }
}
let words = ["banana", "kiwi", "apple"]
var s = Sorter(rule: <)
print(s.sort(words))
s.rule = { $0.count < $1.count }
print(s.sort(words))Çıktı:
["apple", "banana", "kiwi"]
["kiwi", "apple", "banana"]Strateji, algoritmanın içindeki switch ifadesinin yerini alır. Yeni varyantlar yeni türler (veya closure'lar) olur ve bunları kullanan kod değişmeden kalır:
// strateji olmadan: her yeni seçenek bu fonksiyonu düzenler
func cost(kind: String, weight: Int) -> Int {
switch kind { case "standard": return 5 + weight; default: return 15 + weight * 2 }
}
// strateji ile: Checkout asla değişmez
struct Overnight: ShippingStrategy { func cost(weight: Int) -> Int { 40 } }Stratejiler, örneğin küçük bir fabrikayla bir kullanıcı ayarından olmak üzere verilerden seçilebilir:
protocol Discount { func apply(_ price: Int) -> Int }
struct NoDiscount: Discount { func apply(_ p: Int) -> Int { p } }
struct Percent: Discount { let rate: Int; func apply(_ p: Int) -> Int { p - p * rate / 100 } }
func discount(for member: String) -> any Discount {
member == "gold" ? Percent(rate: 20) : NoDiscount()
}
print(discount(for: "gold").apply(200))
print(discount(for: "basic").apply(200))Çıktı:
160
200Görev
KolayBir oyun karakterinin saldırısı bir stratejidir. Attack protokolünde name ve damage(strength:) -> Int bulunur. Sword (strength * 2), Bow (strength + 5) ve Magic uygulayın (saklanan bir mana; mana en az 10 iken hasar strength * 3, aksi hâlde 1 olur; damage kendisi mana değerini değiştirmez). Hero, strength ve attack değerlerini saklar ve strike(), Ada hits with sword for 20 döndürür.
Sağlanan kod, kahramanın adını ve gücünü okur, ardından equip sword, equip bow, equip magic 15 veya strike komutlarını işler. Her saldırının sonucunu yazdırır.
Kodunuz Attack.swift, Sword.swift, Bow.swift, Magic.swift ve Hero.swift dosyalarına yazılmalıdır. main.swift, sağlanan giriş/çıkış kodunu içerir ve düzenlenemez.
Kendin dene
// Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
var input: [String] = []
while let line = readLine() { input.append(line) }
let head = input[0].split(separator: ",").map(String.init)
var hero = Hero(name: head[0], strength: Int(head[1])!, attack: Sword())
for cmd in input.dropFirst() {
let p = cmd.split(separator: " ").map(String.init)
if p[0] == "strike" { print(hero.strike()); continue }
switch p[1] {
case "bow": hero.attack = Bow()
case "magic": hero.attack = Magic(mana: Int(p[2])!)
default: hero.attack = Sword()
}
}
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
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıfları TanımlamaMetotlar ve selfBaşlatıcılarSınıflar ReferanstırTekrar - Kütüphane Kartı4Kapsülleme
Erişim DenetimiDışarıdan Salt OkunurDurumu KorumaBaşarısız Olabilen BaşlatıcılarTekrar - Banka Hesabı7Polimorfizm ve Generic'ler
PolimorfizmTür DönüşümüGeneric FonksiyonlarGeneric TürlerTekrar - Şekil Hesaplayıcı2Struct Yapıları ve Değer Türleri
Struct YapılarıDeğer SemantiğiDeğiştirici MetotlarStruct mı Class mıTekrar - Envanter Öğesi5Kalıtım
Alt sınıflarMetotları Geçersiz KılmaBaşlatıcılar ve superfinal ve HiyerarşilerTekrar - Çalışan Hiyerarşisi11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç AlmaKendi başına pratik yap: Swift playground