תבנית שיטת התבנית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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() -> voidplay() היא התבנית: כל שלב נטען, מזמן את האויבים שלו ומסתיים, לפי הסדר הזה. השלבים שמשתנים הם מופשטים, ולכן כל מחלקת משנה צריכה לכתוב אותם:
# 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() ללא שינוי וכל שלב פועל לפי אותו סדר.
אתגר
בינונימשחק מייצא את הניקוד שלו בשני פורמטים, תוך שימוש באותם שלבים. השורות הן 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)
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח selfמתודותמאפייניםבנאי (_init)חזרה – מחשבון פשוט2מאפייני מחלקה
משתני מופע לעומת משתנים סטטייםפונקציות סטטיותקובעי מאפייניםמאחזרי מאפייניםפרטיים לפי מוסכמהסיכום – מנהל חשבון בנק5כימוס
איברים ציבוריים ופרטייםאימות באמצעות Settersהסתרת מידעמאפיינים לקריאה בלבדסיכום – מערכת לניהול רשומות תלמידיםתרגלו בעצמכם: קומפיילר GDScript אונליין