مقدمة إلى أنماط التصميم
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 45 من 65.
نمط التصميم هو طريقة معروفة ومسمّاة لتنظيم الأصناف من أجل مشكلة تتكرر في برنامج بعد آخر. وهو ليس مكتبة ولا شفرة تنسخها، بل يصف الكائنات الموجودة، ومسؤولية كل منها، وكيفية عملها معًا. تكتب الشفرة بنفسك بما يناسب لعبتك.
تمنح الأنماط المطورين أيضًا مفردات مشتركة. فقولك «تأتي الأعداء من مصنع» أو «يراقب شريط الصحة اللاعب» يخبر زميلًا لك بكيفية تنظيم الشيفرة قبل أن يفتح ملفًا.
إليك مشكلةً يحلّها النمط. يتطلب بدء مستوى التفاعل مع ثلاثة كائنات، وكل نص برمجي يبدأ مستوى يكرر هذه الأسطر:
var music := MusicPlayer.new()
var level_map := LevelMap.new()
var hud := Hud.new()
music.play("forest.ogg")
level_map.load_map(1)
hud.show_hearts(3)يضع نمط Facade صنفًا واحدًا أمام تلك الكائنات ويمنحه طريقة بسيطة واحدة:
# game_facade.gd
class_name GameFacade
extends RefCounted
var music := MusicPlayer.new()
var level_map := LevelMap.new()
var hud := Hud.new()
func start_level(number: int) -> void:
music.play("forest.ogg")
level_map.load_map(number)
hud.show_hearts(3)# main.gd
var game := GameFacade.new()
game.start_level(1)Music: playing forest.ogg
Map: level 1 loaded
HUD: hearts 3يستدعي بقية البرنامج start_level()، وعند تغيير طريقة بدء المستوى، تعدّل ملفًا واحدًا.
تُصنَّف الأنماط بحسب المشكلة التي تحلّها:
- تتحكم الأنماط الإنشائية في كيفية إنشاء الكائنات: Singleton، Factory.
- تجمع الأنماط البنيوية الكائنات في هياكل أكبر: Facade، Adapter، Decorator، Composite.
- تنظّم الأنماط السلوكية كيفية عمل الكائنات معًا: Observer، Strategy، Command، Template Method، State.
يتناول هذا الفصل والفصل التالي هذه الأنماط. يُبنى كل نمط منها على ما تعرفه بالفعل: الأصناف في ملفات مستقلة، والوراثة، وتعدد الأشكال، والتركيب، والإشارات.
التحدي
سهلتبدأ اللعبة المستويات وتنهيها من خلال ثلاثة كائنات مكتوبة مسبقًا: MusicPlayer (music_player.gd) وLevelMap (level_map.gd) وHud (hud.gd). اكتب الواجهة GameFacade أمامها:
- أنشئ كائنًا واحدًا من كل من
MusicPlayerوLevelMapوHudفي متغيرات الأعضاء الخاصة بها. - تشغّل
start_level(number, hearts)المقطوعة الموسيقيةlevel_N.ogg(حيث N هو رقم المستوى)، أوboss.oggعندما يكون الرقم من مضاعفات5، ثم تحمّل خريطة ذلك المستوى، ثم تعرض القلوب. - تخفي
quit_level()واجهة HUD، ثم توقف الموسيقى.
يقرأ الكود المُقدَّم عدد الأوامر التالية، ثم أمرًا واحدًا في كل سطر: start NUMBER HEARTS أو quit. بالنسبة إلى start 5 2 وquit، يكون الناتج:
Music: playing boss.ogg
Map: level 5 loaded
HUD: hearts 2
HUD: hidden
Music: stoppedضع الكود في game_facade.gd. يحتوي main.gd على كود الإدخال/الإخراج المُقدَّم، ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# كود الإدخال/الإخراج المقدَّم: اتركه كما هو
var game := GameFacade.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "start":
game.start_level(int(parts[1]), int(parts[2]))
elif parts[0] == "quit":
game.quit_level()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت