نمط الـ Iterator
جزء من قسم البرمجة كائنية التوجه في رحلة Lua على Coddy. الدرس 64 من 70.
عندما تكون لديك مجموعة من items مخزّنة داخل كائن، فغالبًا ما تريد إجراء loop عليها. تعمل حلقة for generic في Lua بشكل رائع مع المكررات المخصّصة، ويمكنك بناء هذه الوظيفة مباشرةً داخل أصنافك.
يتيح Iterator pattern للكائن التحكم في كيفية اجتياز بياناته الداخلية. يستخدم أحد الأساليب الأنيقة __call metamethod، الذي يجعل الكائن قابلاً للاستدعاء مثل function. يُرجع كل استدعاء العنصر item التالي حتى لا يتبقى more.
local Collection = {}
Collection.__index = Collection
function Collection:new()
local obj = { items = {}, index = 0 }
setmetatable(obj, Collection)
return obj
end
function Collection:add(item)
table.insert(self.items, item)
end
function Collection:__call()
self.index = self.index + 1
return self.items[self.index]
end
مع تعريف __call، يمكنك التكرار باستخدام حلقة while أو تمرير الكائن مباشرةً إلى for عام:
local bag = Collection:new()
bag:add("apple")
bag:add("banana")
for item in bag do
print(item)
end
يستدعي bag() loop بشكل متكرر. عندما تُرجع __call القيمة nil (أي لا مزيد من items)، يتوقف loop. ي encapsulate هذا النمط منطق iteration داخل الكائن نفسه، مما يمنحك تحكمًا كاملًا في كيفية الوصول إلى items وترتيب الوصول إليها.
التحدي
سهللنُنشئ class باسم Playlist يمكنك إجراء iteration عليه باستخدام حلقة for generic في Lua! ستنفّذ نمط Iterator باستخدام metamethod باسم __call، مما يتيح اجتياز قائمة التشغيل أغنيةً تلو الأخرى.
ستنظّم الشيفرة عبر ملفين:
Playlist.lua: أنشئ class باسم Playlist يخزّن الأغاني داخليًا. يجب أن يحتوي class على Constructor باسم:new()يهيّئ قائمة أغاني empty ويضبط index الخاص بـ iteration على 0. أضف method باسم:addSong(title)لإضافة الأغاني إلى قائمة التشغيل. والأهم من ذلك، نفّذ metamethod باسم__callبحيث يعيد، في كل مرة يتم فيها "called" قائمة التشغيل، الأغنية التالية في القائمة (أوnilعند عدم وجود المزيد من الأغاني).main.lua: استورد module Playlist وأنشئ قائمة تشغيل جديدة. أضف إليها الأغاني استنادًا إلى المدخلات التي تتلقاها، ثم استخدم حلقةforgeneric لإجراء iteration عبر قائمة التشغيل وطباعة عنوان كل أغنية في سطر منفصل.
تكمن روعة نمط Iterator في أن كائن Playlist الخاص بك يصبح قابلًا للاستدعاء؛ فعند استخدامه في حلقة for، تستدعيه Lua بشكل متكرر حتى يعيد nil، مما يمنحك كل أغنية بالتسلسل.
ستتلقى ثلاث مدخلات، تمثّل كل منها عنوان أغنية لإضافتها إلى قائمة التشغيل (بالترتيب).
على سبيل المثال، إذا كانت المدخلات هي Bohemian Rhapsody وStairway to Heaven وHotel California، فيجب أن يكون الناتج:
Bohemian Rhapsody
Stairway to Heaven
Hotel Californiaإذا كانت المدخلات هي Yesterday وImagine وLet It Be، فيجب أن يكون الناتج:
Yesterday
Imagine
Let It Beجرّب بنفسك
-- استورد وحدة Playlist
local Playlist = require('Playlist')
-- اقرأ ثلاثة عناوين أغاني من الإدخال
local song1 = io.read()
local song2 = io.read()
local song3 = io.read()
-- TODO: أنشئ قائمة تشغيل جديدة باستخدام Playlist:new()
-- TODO: أضف الأغاني الثلاث إلى قائمة التشغيل باستخدام :addSong()
-- TODO: استخدم حلقة for عامة للتكرار عبر قائمة التشغيل
-- واطبع عنوان كل أغنية في سطر خاص به
-- Hint: for song in playlist do ... end
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
4مشروع: بنك رقمي
إعداد المشروعطريقة الإيداع7تعدد الأشكال وإعادة التعريف
إعادة تعريف الدوالاستدعاء دوال الفئة الأبDuck Typingواجهة مشتركةالتحقق من النوعمراجعة - أدوار الموظفين2نمط النموذج الأولي للفئات
مفهوم النموذج الأوليالربط باستخدام __indexالمنشئ :new()تهيئة الخصائصنسخ مستقلةملخص - مصنع السيارات5تحميل المعاملات في OOP
جمع الكائناتطرح الكائناتدمج الكائناتمقارنة الكائنات (<, >)مراجعة - رياضيات المحفظة8التغليف
اصطلاحات التسميةاستخدام Closures للخصوصيةالوصول عبر Closuresجداول للقراءة فقطمنطق التحقق من الصحةمراجعة - الخزنة الآمنة11أنماط التصميم (مبسط)
دوال المصنعجدول Singletonنمط الـ Iteratorالمراقب (المستمع)مراجعة - مصنع الـ Logger3حالة الكائن وسلوكه
متغيرات النسخةدالات الجلب (Getter Methods)دالات التعيين (Setter Methods)الخصائص المحسوبةتنسيق النصوصالتحقق من المساواةمراجعة - درجة الطالب6أساسيات الوراثة
إعداد الوراثةوراثة الـ Methodsتوسيع الـ Constructorإضافة Methods للابنالمشترك مقابل الفريدملخص - التسلسل الهرمي للأشكالتدرّب بنفسك: مترجم Lua عبر الإنترنت