Menu
CoddyTech

Dekoratör Kalıbı

Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 52 / 65.

Decorator deseni, bir nesneyi aynı yöntemlere sahip başka bir nesnenin içine sararak ona davranış ekler. Her sarmalayıcı, içindeki nesneyi çağırır ve kendi katkısını ekler; sarmalayıcılar istenen herhangi bir sırayla üst üste eklenebilir.

# weapon.gd
class_name Weapon
extends RefCounted

func get_damage() -> int:
	return 10

func describe() -> String:
	return "Sword"

Dekoratör, Weapon sınıfını genişletir; bu nedenle bir silahın beklendiği her yerde kullanılabilir ve sardığı silahı tutar:

# fire_enchant.gd
class_name FireEnchant
extends Weapon

var inner: Weapon

func _init(wrapped: Weapon) -> void:
	inner = wrapped

func get_damage() -> int:
	return inner.get_damage() + 5

func describe() -> String:
	return inner.describe() + " + Fire"

SharpEnchant aynı şekilde yazılır, ancak get_damage() metodu inner.get_damage() * 2 değerini döndürür ve describe() metodu " + Sharp" ekler.

# main.gd
var weapon: Weapon = Weapon.new()
print(weapon.describe(), ": ", weapon.get_damage())
weapon = FireEnchant.new(weapon)
weapon = SharpEnchant.new(weapon)
print(weapon.describe(), ": ", weapon.get_damage())
Sword: 10
Sword + Fire + Sharp: 30

Çağrılar içe doğru ilerler: SharpEnchant, FireEnchant'e sorar, o da kılıca sorar. Kılıç 10 döndürür, ateş bunu 15 yapar ve keskinlik bunu ikiye katlayarak 30 yapar. Diğer sırada, FireEnchant.new(SharpEnchant.new(Weapon.new())), hasar 10 * 2 + 5 olur; bu da 25 eder.

Decorator'lar olmadan, her birleşim için ayrı bir alt sınıf gerekirdi: FireSword, SharpSword, FireSharpSword ve benzerleri. Bunlarla, iki küçük sınıf tüm birleşimleri kapsar ve yeni bir büyüleme için bir dosya daha eklemek yeterlidir.

challenge icon

Görev

Orta

Bir kahve dükkânı, içecekleri dekoratörlerle oluşturur. Beverage (beverage.gd), cost() ve description() işlevlerini bildirir; Espresso (espresso.gd, $3) ve Tea (tea.gd, $2) yazılmıştır. Her dekoratör, sardığı içeceği inner içinde saklar (yapıcılar yazılmıştır). Şunlarda cost() ve description() işlevlerini geçersiz kıl:

  • Milk: maliyeti 1 artırır ve açıklamaya + Milk ekler.
  • Mocha: maliyeti 2 artırır ve + Mocha ekler.
  • Large: içindeki her şeyin maliyetini ikiye katlar ve açıklamanın önüne Large ekler.

Verilen kod, ardından kaç sipariş geleceğini okur ve her satırda bir sipariş alır: içecek (espresso veya tea) ve soldan sağa uygulanan ek malzemeler. espresso milk large ve tea mocha milk için çıktı şöyledir:

Large Espresso + Milk: $8
Tea + Mocha + Milk: $5

Kodunu milk.gd, mocha.gd ve large.gd dosyalarına yaz. main.gd, verilen girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

extends Node

func _ready():
	# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var words := OS.read_string_from_stdin().split(" ")
		var drink: Beverage = Tea.new()
		if words[0] == "espresso":
			drink = Espresso.new()
		for extra in words.slice(1):
			match extra:
				"milk":
					drink = Milk.new(drink)
				"mocha":
					drink = Mocha.new(drink)
				"large":
					drink = Large.new(drink)
		print("%s: $%d" % [drink.description(), drink.cost()])
quiz iconKendini test et

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

Kendi başına pratik yap: Online GDScript derleyicisi