Mixins بسيطة
جزء من قسم البرمجة كائنية التوجه في رحلة Lua على Coddy — الدرس 51 من 70.
يسمح لك التركيب (Composition) بوضع كائنات داخل كائنات أخرى. ولكن ماذا لو كنت تريد مشاركة السلوك عبر فئات (classes) غير مرتبطة؟
قد يحتاج كل من Player و MenuItem إلى طريقة :describe()، ولكنهما لا يتشاركان في فئة أب (parent class) واحدة. وهنا يأتي دور الـ mixins.
الـ mixin هو ببساطة جدول يحتوي على دوال. تقوم بـ "خلط" هذه الدوال داخل class عن طريق نسخها إليها:
local Printable = {}
function Printable:describe()
print("Object: " .. tostring(self))
end
function Printable:log(message)
print("[LOG] " .. message)
endلتطبيق هذا الـ mixin على فئة (class)، تقوم بنسخ كل دالة من جدول الـ mixin إلى جدول الفئة:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local Player = {}
Player.__index = Player
applyMixin(Player, Printable) -- الآن يمتلك Player كل من :describe() و :log()بعد تطبيق الـ mixin، يمكن لأي مثيل Player استدعاء تلك الدوال كما لو كانت مُعرفة مباشرةً في الـ class:
local p = setmetatable({}, Player)
p:log("Player created") -- [LOG] تم إنشاء اللاعبعلى عكس الوراثة، لا تنشئ الـ mixins علاقة أب-ابن. أنت ببساطة تقوم بنسخ الدوال من جدول إلى آخر.
هذا يجعل الـ mixins مثالية لمشاركة السلوكيات المساعدة — مثل طرق التسجيل (logging)، أو التسلسل (serialization)، أو دوال الوصف — عبر الفئات (classes) التي لا يوجد بينها أي قاسم مشترك آخر.
التحدي
سهللنقم ببناء نظام وسوم (tagging system) باستخدام الـ mixins! ستقوم بإنشاء mixin باسم Taggable يمكن تطبيقه على أي فئة، مما يمنح الكائنات القدرة على إدارة مجموعة من الوسوم — وهو أمر مفيد لتصنيف العناصر، أو المنشورات، أو أي كيان يحتاج إلى تسميات.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
Taggable.lua: أنشئ جدول mixin يحتوي على طريقتين (methods)::addTag(tag)— يضيف وسماً إلىself.tags(يفترض وجود الجدول):listTags()— يطبع جميع الوسوم بالتنسيقTags: tag1, tag2, tag3(أوTags: noneإذا كان فارغاً)
Article.lua: أنشئ فئة Article مع منشئ (constructor) باسم:new(title)يقوم بتخزين العنوان ويهيئ جدولtagsفارغاً. قم بتطبيق Taggable mixin لمنح مثيلات Article قدرات الوسم. قم بتضمين طريقة:getTitle()التي تعيد عنوان المقال.main.lua: اكتب الدالة المساعدةapplyMixinهنا (ستستخدمها في Article.lua عبر require). ثم اقرأ المدخلات لعنوان المقال ووسمين. أنشئ Article، وأضف كلا الوسمين إليه، واطبع العنوان، واعرض قائمة بجميع الوسوم.
ستتلقى ثلاثة مدخلات:
- عنوان المقال (سلسلة نصية)
- الوسم الأول المراد إضافته (سلسلة نصية)
- الوسم الثاني المراد إضافته (سلسلة نصية)
يجب أن يعرض مخرجك عنوان المقال متبوعاً بوسومه:
Title: {title}
Tags: {tag1}, {tag2}على سبيل المثال، إذا كانت المدخلات هي Lua Basics، و programming، و tutorial، فيجب أن يكون المخرج:
Title: Lua Basics
Tags: programming, tutorialتذكر: تعمل طرق الـ mixin لأن مثيلات Article تحتوي على جدول tags يمكن لطرق الـ mixin العمل عليه. الـ mixin لا ينشئ هذا الجدول — بل يقوم منشئ Article الخاص بك بذلك. الـ mixin يوفر فقط السلوك المشترك!
جرّب بنفسك
-- الملف الرئيسي لنظام الوسم (tagging system)
local Taggable = require('Taggable')
local Article = require('Article')
-- TODO: تنفيذ دالة applyMixin
-- يجب أن تقوم هذه الدالة بنسخ جميع الأساليب (methods) من جدول mixin إلى جدول target
function applyMixin(target, mixin)
-- TODO: قم بالمرور عبر الـ mixin ونسخ كل دالة إلى target
end
-- قراءة المدخلات
local title = io.read()
local tag1 = io.read()
local tag2 = io.read()
-- TODO: إنشاء Article بالعنوان المعطى
-- TODO: إضافة كلا الوسمين إلى المقال
-- TODO: طباعة العنوان بالتنسيق التالي: Title: {title}
-- TODO: عرض قائمة بجميع الوسوم باستخدام دالة listTags
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
4مشروع: بنك رقمي
إعداد المشروعطريقة الإيداع7تعدد الأشكال وإعادة التعريف
إعادة تعريف الدوالاستدعاء دوال الفئة الأبDuck Typingواجهة مشتركةالتحقق من النوعمراجعة - أدوار الموظفين2نمط النموذج الأولي للفئات
مفهوم النموذج الأوليالربط باستخدام __indexالمنشئ :new()تهيئة الخصائصنسخ مستقلةملخص - مصنع السيارات5تحميل المعاملات في OOP
جمع الكائناتطرح الكائناتدمج الكائناتمقارنة الكائنات (<, >)مراجعة - رياضيات المحفظة8التغليف
اصطلاحات التسميةاستخدام Closures للخصوصيةالوصول عبر Closuresجداول للقراءة فقطمنطق التحقق من الصحةمراجعة - الخزنة الآمنة11أنماط التصميم (مبسط)
دوال المصنعجدول Singletonنمط الـ Iteratorالمراقب (المستمع)مراجعة - مصنع الـ Logger3حالة الكائن وسلوكه
متغيرات النسخةدالات الجلب (Getter Methods)دالات التعيين (Setter Methods)الخصائص المحسوبةتنسيق النصوصالتحقق من المساواةمراجعة - درجة الطالب6أساسيات الوراثة
إعداد الوراثةوراثة الـ Methodsتوسيع الـ Constructorإضافة Methods للابنالمشترك مقابل الفريدملخص - التسلسل الهرمي للأشكال9التركيب و Mixins
علاقة "يحتوي على" (Has-A)التفويض (Delegation)Mixins بسيطةتطبيق Mixins متعددةMixins مقابل الوراثةملخص - تجميع الروبوت