Pola Composite
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GDScript di Coddy. Pelajaran 55 dari 65.
Pola Composite membangun pohon yang membuat satu object dan sekelompok object memiliki method yang sama, sehingga kodemu dapat memperlakukan seluruh kelompok seperti satu item. Sebuah tas berisi item, sebuah tas dapat berisi tas lain, dan kamu dapat menanyakan beratnya dengan cara yang sama.
Kedua jenis memiliki parent abstrak yang sama:
# entry.gd
@abstract
class_name Entry
extends RefCounted
var entry_name: String
@abstract func get_weight() -> int
@abstract func display(indent: String) -> voidDaunnya adalah satu item:
# 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, ")")Komposit menampung entri lain dan menjawab dengan menanyai setiap entri tersebut. Sebuah tas memiliki bobot 1:
# 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() tidak pernah memeriksa apakah sebuah entri adalah item atau tas: fungsi ini memanggil method yang sama pada masing-masing, dan tas di dalamnya menjawab dengan menanyakan isinya sendiri. Rekursi itu menelusuri seluruh pohon, sedalam apa pun.
Tautan berjalan satu arah, dari tas ke isinya. Jika setiap entri juga menyimpan informasi tentang tas tempatnya berada, setiap tas dan entrinya akan saling menunjuk, membentuk siklus referensi yang tidak pernah dibebaskan. Saat entri perlu mengetahui lokasinya, teruskan informasi itu sebagai argumen, seperti display() meneruskan indentasi.
Tantangan
SedangBuat pohon folder dengan pola Composite. DiskEntry (disk_entry.gd) mendeklarasikan get_size(), count_files(), dan list_lines(indent). Tulis:
FileEntry: ukurannya adalahsizemiliknya sendiri, dihitung sebagai1file, danlist_lines()mencetak indentasi, laluNAME (SIZE KB).FolderEntry:add(entry)menyimpan child. Ukurannya adalah jumlah ukuran semua child-nya, jumlah file-nya adalah jumlah file semua child-nya, danlist_lines()mencetak indentasi, laluNAME/ (SIZE KB), kemudian mencantumkan setiap child dengan indentasi ditambah dua spasi.
Kode yang disediakan membuat pohon dari input (jumlah baris berikutnya, lalu folder NAME, file NAME SIZE atau end, yang menutup folder saat ini), mencantumkannya, dan mencetak totalnya. Untuk folder Root yang berisi notes.txt (4 KB) dan folder Music dengan song.mp3 (300 KB), output-nya adalah:
Root/ (304 KB)
notes.txt (4 KB)
Music/ (300 KB)
song.mp3 (300 KB)
Total: 304 KB, files: 2Tulis kodemu di file_entry.gd dan folder_entry.gd. main.gd berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
extends Node
func _ready():
# Kode input/output yang disediakan: biarkan apa adanya
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()])
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengantar OOPclass dan objectKata Kunci selfmethodpropertyKonstruktor (_init)Ringkasan: Kalkulator Sederhana4Polimorfisme
Method Overriding Sekali LagiDuck TypingKelas Abstrak dan MethodDesain InterfaceRingkasan: Kalkulator Bentuk7Sinyal
Apa itu Sinyal?Mendeklarasikan dan MemancarkanMenghubungkan ke SinyalSinyal dengan ArgumenRangkuman, Sistem Kesehatan10Pola Desain Bagian 2
Pola CommandPola AdapterPola DecoratorPola Template MethodPola StatePola Composite2Property class
Variabel instance vs. variabel statisFungsi statisSetter propertyGetter propertyPrivat berdasarkan konvensiRangkuman: Pengelola Rekening Bank5Enkapsulasi
Member Publik dan PrivatValidasi dengan SetterPenyembunyian InformasiProperty Hanya-BacaRingkasan: Sistem Catatan Siswa8Konsep OOP Lanjutan
Komposisi vs PewarisanInner ClassNode sebagai KomponenRefCounted vs NodeEnum dalam Class11Proyek: Manajemen Perpustakaan
Gambaran Umum Proyekclass Buku dan PenggunaLatihan sendiri: Compiler GDScript online