نمط الأوامر
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 50 من 65.
يحوّل نمط Command الإجراء إلى كائن. يخزّن الكائن كل ما يلزم لتنفيذ الإجراء، لذا يمكنك الاحتفاظ به في قائمة، أو تنفيذه لاحقًا، أو التراجع عنه.
لكل أمر الطريقتان نفسيهما، وتُعلَن عنهما فئة أب مجرّدة:
# command.gd
@abstract
class_name Command
extends RefCounted
@abstract func execute() -> void
@abstract func undo() -> voidيحتفظ الأمر الملموس بالكائن الذي يعمل عليه، ويُسمى المستقبل، وببيانات الإجراء. المستقبل هنا هو Hero الذي لديه var x := 0:
# move_command.gd
class_name MoveCommand
extends Command
var hero: Hero
var dx: int
func _init(target: Hero, step: int) -> void:
hero = target
dx = step
func execute() -> void:
hero.x += dx
func undo() -> void:
hero.x -= dxينفّذ المستدعي الأوامر ويتذكرها. ولا يحتاج مطلقًا إلى معرفة ما يفعله الأمر:
# command_history.gd
class_name CommandHistory
extends RefCounted
var done: Array[Command] = []
func run(command: Command) -> void:
command.execute()
done.append(command)
func undo_last() -> void:
if done.is_empty():
return
var last: Command = done.pop_back()
last.undo()# main.gd
var hero := Hero.new()
var history := CommandHistory.new()
history.run(MoveCommand.new(hero, 3))
history.run(MoveCommand.new(hero, 2))
print(hero.x)
history.undo_last()
print(hero.x)5
3السجل عبارة عن مكدّس: تأخذ pop_back() أحدث أمر، لذا يتراجع الإلغاء عبر الإجراءات بترتيب عكسي. وتتيح لك الكائنات نفسها إعادة تعيين المفاتيح (يرتبط المفتاح بأمر)، وإعادة التشغيل (تشغيل القائمة المحفوظة مرة أخرى)، وقوائم انتظار الأدوار.
تسير المراجع في اتجاه واحد: تشير الأوامر إلى البطل، ولا يعرف البطل عنها شيئًا. وإذا خزّن البطل أوامره أيضًا، فستُبقي الكائنات بعضها بعضًا حيّةً ولن يُحرَّر أيٌّ منها أبدًا.
التحدي
سهليتحرك بطل على شبكة، ويمكن التراجع عن كل حركة. يعرّف Command (command.gd) الدالتين execute() وundo()، ويحتوي Hero (hero.gd) على x وy وposition_text(). اكتب:
MoveCommand: يخزّن المُنشئ البطل والخطوتينstep_xوstep_y. تضيفexecute()الخطوتين إلىxوyالخاصتين بالبطل، وتطرحهماundo().CommandHistory: تنفّذrun(command)الأمر وتخزّنه. تتراجعundo_last()عن أحدث أمر مخزّن، وتزيله، وتُرجعtrue؛ وإذا لم يكن هناك شيء مخزّن، فتُرجعfalse.
يقرأ الكود المُعطى عدد الإجراءات التالية، ثم يقرأ إجراءً واحدًا في كل سطر (up أو down أو left أو right أو undo)، ويطبع الموقع بعد كل إجراء. تُنقص up قيمة y بمقدار واحد. بالنسبة إلى right وup وundo وundo وundo، يكون الناتج:
right -> (1, 0)
up -> (1, -1)
undo -> (1, 0)
undo -> (0, 0)
Nothing to undoضع الكود في move_command.gd وcommand_history.gd. يحتوي main.gd على كود الإدخال والإخراج المُعطى، ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# كود الإدخال/الإخراج المقدَّم: اتركه كما هو
var hero := Hero.new()
var history := CommandHistory.new()
var steps := {"up": [0, -1], "down": [0, 1], "left": [-1, 0], "right": [1, 0]}
var count := int(OS.read_string_from_stdin())
for i in count:
var action := OS.read_string_from_stdin()
if action == "undo":
if history.undo_last():
print("undo -> ", hero.position_text())
else:
print("Nothing to undo")
else:
var step: Array = steps[action]
history.run(MoveCommand.new(hero, step[0], step[1]))
print(action, " -> ", hero.position_text())
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت