Bileşik Kalıp
Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 55 / 65.
Composite tasarım deseni, tek bir nesnenin ve bir nesne grubunun aynı yöntemlere sahip olduğu ağaçlar oluşturur; böylece kod, bütün bir grubu tek bir öğe gibi ele alabilir. Bir çanta öğeler içerir, bir çanta başka çantalar içerebilir ve ağırlığını hepsine aynı şekilde sorabilirsiniz.
Her iki tür de ortak bir soyut üst sınıfı paylaşır:
# entry.gd
@abstract
class_name Entry
extends RefCounted
var entry_name: String
@abstract func get_weight() -> int
@abstract func display(indent: String) -> voidYaprak tek bir öğedir:
# item.gd
class_name Item
extends Entry
var weight: int
func _init(n: String, w: int) -> void:
entry_name = n
weight = w
func get_weight() -> int:
return weight
func display(indent: String) -> void:
print(indent, entry_name, " (", weight, ")")Bileşik, başka girdileri içinde tutar ve her birine sorarak yanıt verir. Bir çanta kendi başına 1 ağırlığındadır:
# bag.gd
class_name Bag
extends Entry
var contents: Array[Entry] = []
func _init(n: String) -> void:
entry_name = n
func add(entry: Entry) -> void:
contents.append(entry)
func get_weight() -> int:
var total := 1
for entry in contents:
total += entry.get_weight()
return total
func display(indent: String) -> void:
print(indent, entry_name, " [", get_weight(), "]")
for entry in contents:
entry.display(indent + " ")# main.gd
var pouch := Bag.new("Pouch")
pouch.add(Item.new("Gem", 2))
var backpack := Bag.new("Backpack")
backpack.add(Item.new("Sword", 8))
backpack.add(pouch)
backpack.display("")Backpack [12]
Sword (8)
Pouch [3]
Gem (2)Bag.get_weight() bir girdinin eşya mı yoksa çanta mı olduğunu asla kontrol etmez: her biri için aynı yöntemi çağırır ve içindeki bir çanta kendi içeriğine sorarak yanıt verir. Bu özyineleme, ne kadar derin olursa olsun tüm ağaç yapısını dolaşır.
Bağlantılar tek yönlüdür; bir torbadan içindekilere gider. Her girdi içinde bulunduğu torbayı da saklasaydı, her torba ve girdileri birbirini işaret ederdi; bu da hiçbir zaman serbest bırakılmayan bir başvuru döngüsü oluştururdu. Bir girdinin nerede olduğunu bilmesi gerektiğinde, display() girintiyi nasıl geçiriyorsa bu bilgiyi de bir bağımsız değişken olarak aşağıya aktarın.
Görev
OrtaComposite deseniyle bir klasör ağacı oluşturun. DiskEntry (disk_entry.gd), get_size(), count_files() ve list_lines(indent) işlevlerini bildirir. Şunları yazın:
FileEntry: boyutu kendisizedeğeridir,1dosya sayılır velist_lines()önce girintiyi, ardındanNAME (SIZE KB)ifadesini yazdırır.FolderEntry:add(entry)bir alt öğeyi saklar. Boyutu alt öğelerinin boyutlarının toplamı, dosya sayısı onların sayılarının toplamıdır velist_lines()önce girintiyi, ardındanNAME/ (SIZE KB)ifadesini yazdırır, sonra her alt öğeyi girintiye iki boşluk ekleyerek listeler.
Sağlanan kod, girdiden ağacı oluşturur (kaç satır olduğu, ardından folder NAME, file NAME SIZE veya geçerli klasörü kapatan end), ağacı listeler ve toplamları yazdırır. notes.txt (4 KB) içeren bir Root klasörü ve song.mp3 (300 KB) içeren bir Music klasörü için çıktı şöyledir:
Root/ (304 KB)
notes.txt (4 KB)
Music/ (300 KB)
song.mp3 (300 KB)
Total: 304 KB, files: 2Kodunuzu file_entry.gd ve folder_entry.gd dosyalarına yazın. 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 open_folders: Array[FolderEntry] = []
var root: FolderEntry = null
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
match parts[0]:
"folder":
var folder := FolderEntry.new(parts[1])
if open_folders.is_empty():
root = folder
else:
open_folders.back().add(folder)
open_folders.append(folder)
"file":
open_folders.back().add(FileEntry.new(parts[1], int(parts[2])))
"end":
open_folders.pop_back()
root.list_lines("")
print("Total: %d KB, files: %d" % [root.get_size(), root.count_files()])
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 SistemiKendi başına pratik yap: Online GDScript derleyicisi