Menu
CoddyTech

תבנית שיטת התבנית

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GDScript של Coddy. שיעור 53 מתוך 65.

תבנית Template Method קובעת את סדר השלבים של אלגוריתם במחלקת־אב ומאפשרת לכל מחלקת־בת למלא חלק מהשלבים. המתודה במחלקת־האב שמריצה את השלבים היא מתודת התבנית.

# level.gd
@abstract
class_name Level
extends RefCounted

func play() -> void:
	print("Loading ", get_level_name())
	spawn_enemies()
	print("Level complete!")

@abstract func get_level_name() -> String
@abstract func spawn_enemies() -> void

play() היא התבנית: כל שלב נטען, מזמן את האויבים שלו ומסתיים, לפי הסדר הזה. השלבים שמשתנים הם מופשטים, ולכן כל מחלקת משנה צריכה לכתוב אותם:

# forest_level.gd
class_name ForestLevel
extends Level

func get_level_name() -> String:
	return "Forest"

func spawn_enemies() -> void:
	print("3 wolves appear")

CaveLevel נכתב באותו אופן, עם השם "Cave" ועם 5 bats appear.

# main.gd
var levels: Array[Level] = [ForestLevel.new(), CaveLevel.new()]
for level in levels:
	level.play()
Loading Forest
3 wolves appear
Level complete!
Loading Cave
5 bats appear
Level complete!

לשלב יכולה להיות גם ברירת מחדל במחלקת האב, שמחלקת משנה יכולה לדרוס. שלב אופציונלי כזה נקרא hook:

# level.gd
func play() -> void:
	print("Loading ", get_level_name())
	spawn_enemies()
	if has_boss():
		print("The boss arrives")
	print("Level complete!")

func has_boss() -> bool:
	return false

רק שלב שדורס את has_boss() כך שיחזיר true מקבל את שורת הבוס. מחלקות הבת כותבות את השלבים, ומחלקת האב מחליטה מתי הם מתבצעים, לכן מחלקת בת משאירה את play() ללא שינוי וכל שלב פועל לפי אותו סדר.

challenge icon

אתגר

בינוני

משחק מייצא את הניקוד שלו בשני פורמטים, תוך שימוש באותם שלבים. השורות הן Dictionaries עם "name" ועם "score".

  • ב־exporter.gd, כתבו את שיטת התבנית export_rows(rows): היא מדפיסה את header(), אחר כך את format_row(row) עבור כל שורה, ולבסוף את footer(rows). כותרת או כותרת תחתונה שהן מחרוזת ריקה אינן מודפסות. נקודות ההרחבה header() ו־footer() מחזירות כברירת מחדל "", ו־format_row() היא אבסטרקטית.
  • CsvExporter: הכותרת היא name,score, ושורה היא Ada,12. ללא כותרת תחתונה.
  • ListExporter: ללא כותרת, שורה היא * Ada scored 12, והכותרת התחתונה היא Players: N עם מספר השורות.

הקוד שסופק קורא את הפורמט (csv או list), את מספר השורות הבאות, ואז שורת NAME SCORE אחת בכל שורה. עבור list עם Ada 12 ו־Bo 7, הפלט הוא:

* Ada scored 12
* Bo scored 7
Players: 2

הקוד שלכם ייכתב בקבצים exporter.gd, csv_exporter.gd ו־list_exporter.gd. הקובץ main.gd מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.

נסו בעצמכם

extends Node

func _ready():
	# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
	var style := OS.read_string_from_stdin()
	var rows: Array = []
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		rows.append({"name": parts[0], "score": int(parts[1])})
	var exporter: Exporter = CsvExporter.new()
	if style == "list":
		exporter = ListExporter.new()
	exporter.export_rows(rows)
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר GDScript אונליין