Strategy Deseni
Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 49 / 65.
Strategy kalıbı, bir algoritmanın her sürümünü kendi nesnesine koyar; böylece program çalışırken algoritmayı değiştirebilirsin. Algoritmayı kullanan nesneye bağlam denir. Bağlam tek bir yöntemi çağırır ve hangi sürümü barındırdığını önemsemez.
İşte iki saldırı stratejisi: aynı damage() metoduna sahip bir üst sınıf ve bir alt sınıf:
# attack_style.gd
class_name AttackStyle
extends RefCounted
func damage(power: int) -> int:
return power# heavy_attack.gd
class_name HeavyAttack
extends AttackStyle
func damage(power: int) -> int:
return power * 2Bağlam bir strateji depolar ve hesaplamayı ona devreder:
# fighter.gd
class_name Fighter
extends RefCounted
var power := 10
var style: AttackStyle = AttackStyle.new()
func set_style(new_style: AttackStyle) -> void:
style = new_style
func attack() -> void:
print("Hit for ", style.damage(power))# main.gd
var fighter := Fighter.new()
fighter.attack()
fighter.set_style(HeavyAttack.new())
fighter.attack()Hit for 10
Hit for 20Fighter hangi dövüş stiline sahip olduğunu asla kontrol etmez. Yeni bir stil, yeni bir sınıftır ve fighter.gd olduğu gibi kalır; attack() içindeki if style == "heavy" zinciri her stille birlikte büyürdü.
Bir strateji, kendi verisi olmayan küçük bir işlevden ibaretse Callable yeterlidir. Bağlam, işlevi saklar ve onu call() ile çalıştırır:
# price_calculator.gd
class_name PriceCalculator
extends RefCounted
var discount: Callable = func(price): return price
func final_price(price: int) -> int:
return discount.call(price)# main.gd
var calc := PriceCalculator.new()
print(calc.final_price(80))
calc.discount = func(price): return price / 2
print(calc.final_price(80))
calc.discount = func(price): return max(price - 25, 0)
print(calc.final_price(80))80
40
55Bir stratejinin kendi ayarları veya birden fazla yöntemi varsa sınıfları, tek bir kısa hesaplama içinse Callable'ları kullan. Bu fikri daha önce kullandın: sort_custom() işlevine aktardığın karşılaştırma işlevi bir sıralama stratejisidir.
Görev
OrtaBir alışveriş sepeti, ödeme sırasında indirim stratejilerini değiştirebilir. discount.gd içindeki Discount, temel stratejidir: indirim yok. İki strateji daha ve sepeti yaz:
PercentOff(yüzdeyle oluşturulur):apply(total),total - total * percent / 100değerini döndürür (tamsayı aritmetiği) velabel(), yüzde 10 için10% offdeğerini döndürür.FixedOff(bir tutarla oluşturulur):apply(total), toplamdan tutarı çıkarır ancak hiçbir zaman0değerinin altına düşmez velabel(), 30 tutarı için30 offdeğerini döndürür.Cart:set_discount(new_discount)stratejiyi saklar vecheckout()fiyatları toplar ve PRICE, stratejininapply()metodunun döndürdüğü değer olmak üzereSubtotal TOTAL, LABEL, pay PRICEdeğerini döndürür.
Sağlanan kod, fiyatları bir satırda, sonraki ödeme sayısını ve her satırda bir stratejiyi okur: percent N, fixed N veya none. 50 30 40 fiyatları ve percent 10, fixed 30, none stratejileri için çıktı şöyledir:
Subtotal 120, 10% off, pay 108
Subtotal 120, 30 off, pay 90
Subtotal 120, no discount, pay 120Kodunu cart.gd, percent_off.gd ve fixed_off.gd dosyalarına yaz. main.gd, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
extends Node
func _ready():
# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
var cart := Cart.new()
for price in OS.read_string_from_stdin().split(" "):
cart.add_item(int(price))
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "percent":
cart.set_discount(PercentOff.new(int(parts[1])))
elif parts[0] == "fixed":
cart.set_discount(FixedOff.new(int(parts[1])))
else:
cart.set_discount(Discount.new())
print(cart.checkout())
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
1Nesne Yönelimli Programlamanın Temelleri
Harici DosyalarNesne Yönelimli Programlamaya GirişSınıflar ve Nesnelerself Anahtar KelimesiMetotlarÖzelliklerKurucu (_init)Tekrar - Basit Hesap Makinesi4Çok Biçimlilik
Metot Ezme Konusuna Yeniden BakışÖrdek TiplemesiSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı7Sinyaller
Sinyal Nedir?Tanımlama ve Sinyal GöndermeSinyallere BağlanmaArgümanlı SinyallerTekrar - Sağlık Sistemi10Tasarım Kalıpları 2. Bölüm
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıBileşik Kalıp2Sınıf Özellikleri
Örnek ve Statik DeğişkenlerStatik FonksiyonlarÖzellik AyarlayıcılarıÖzellik AlıcılarıGeleneksel Olarak ÖzelTekrar - Banka Hesabı Yöneticisi5Kapsülleme
Public ve Private ÜyelerSetter'larla DoğrulamaBilgi GizlemeSalt Okunur ÖzelliklerTekrar - Öğrenci Kayıt Sistemi3Kalıtım
Temel Kalıtımsuper Anahtar SözcüğüMetot Geçersiz KılmaKalıtım Zincirleriis ile Tür KontrolleriTekrar: Çalışan Hiyerarşisi9Tasarım Desenleri Bölüm 1
Tasarım Desenlerine GirişSingleton DeseniFactory DeseniObserver DeseniStrategy DeseniKendi başına pratik yap: Online GDScript derleyicisi