Menu
CoddyTech
flag Ar iconالعربيةdown icon

نمط الطريقة القالبية

جزء من قسم البرمجة كائنية التوجّه في رحلة 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!

يمكن أن تكون للخطوة أيضًا قيمة افتراضية في الصنف الأب، ويمكن للصنف الفرعي تجاوزها. وتُسمى هذه الخطوة الاختيارية خطافًا:

# 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

التحدي

متوسط

تُصدّر لعبةٌ نتائجها بتنسيقين باستخدام الخطوات نفسها. الصفوف عبارة عن قواميس تحتوي على "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 عبر الإنترنت