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

إخفاء المعلومات

جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 28 من 65.

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

# inventory.gd
class_name Inventory
extends RefCounted

var _counts: Dictionary = {}

func add(item: String, amount: int) -> void:
	_counts[item] = _counts.get(item, 0) + amount

func count(item: String) -> int:
	return _counts.get(item, 0)

func remove(item: String, amount: int) -> bool:
	if count(item) < amount:
		return false
	_counts[item] -= amount
	return true

يستدعي main.gd الدوال add() وcount() وremove() ولا يتعامل مطلقًا مع القاموس. إذا احتفظت Inventory لاحقًا بمصفوفة من الخانات بدلًا من ذلك، فلن يتغير سوى inventory.gd.

كن حذرًا مع دوال getter التي تُرجع مصفوفة أو قاموسًا. يُمرّر GDScript هذه القيم بالمرجع: يحصل المستدعي على المصفوفة الخاصة بالكائن، وليس نسخةً منها، ويمكنه تغييرها دون المرور عبر أساليب الصنف:

# quest_log.gd
var _quests: Array[String] = ["Find the key"]

func get_quests() -> Array[String]:
	return _quests
# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]

أعِد نسخة بدلًا من ذلك. تُنشئ duplicate() مصفوفة جديدة بالعناصر نفسها، لذا تظل التغييرات التي تطرأ عليها خارج الكائن:

func get_quests() -> Array[String]:
	return _quests.duplicate()

بالنسبة إلى القاموس، أو المصفوفة التي تحتوي على مصفوفات أخرى، استخدم duplicate(true): فهي تنسخ المصفوفات والقواميس الداخلية أيضًا.

challenge icon

التحدي

سهل

اكتب الصنف Playlist في الملف playlist.gd. يحتفظ بعناوين الأغاني في المصفوفة الخاصة _songs، ولا تستخدم الشيفرات الأخرى سوى هذه الدوال:

  • تضيف add(title) العنوان وتُرجع true. إذا كان العنوان موجودًا بالفعل في قائمة التشغيل، فلا تغيّر شيئًا وتُرجع false.
  • تزيل remove(title) العنوان وتُرجع true، أو تُرجع false إذا لم يكن موجودًا.
  • تُرجع count() عدد الأغاني.
  • تُرجع get_titles() نسخة من العناوين، حسب ترتيب إضافتها.

تقرأ الشيفرة المرفقة عدد الأوامر، ثم أمرًا واحدًا في كل سطر (add Blue Sky أو remove Blue Sky) وتطبع النتيجة. في النهاية، تأخذ المصفوفة من get_titles()، وتضيف إليها Intruder وتعكس ترتيبها، ثم تطبع عدد الأغاني والعناوين. يجب ألا تتأثر قائمة التشغيل بهذه التغييرات. للأوامر add Blue Sky وadd Rain وadd Blue Sky، تطبع:

Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, Rain

ضع شيفرتك في playlist.gd. يحتوي main.gd على شيفرة الإدخال والإخراج المرفقة، ولا يمكن تعديله.

جرّب بنفسك

extends Node

func _ready():
	# شيفرة الإدخال والإخراج المقدَّمة: اتركها كما هي
	var playlist := Playlist.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ", true, 1)
		var title := parts[1]
		if parts[0] == "add":
			if playlist.add(title):
				print("Added: " + title)
			else:
				print("Already in the playlist: " + title)
		elif playlist.remove(title):
			print("Removed: " + title)
		else:
			print("Not found: " + title)
	# شيفرة تحاول تغيير القائمة التي تحصل عليها
	var titles := playlist.get_titles()
	titles.append("Intruder")
	titles.reverse()
	print("Songs: %d" % playlist.count())
	print(", ".join(playlist.get_titles()))
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجّه

تدرّب بنفسك: مترجم GDScript عبر الإنترنت