Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

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) التي لا يوجد بينها أي قاسم مشترك آخر.

challenge icon

التحدي

سهل

لنقم ببناء نظام وسوم (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، وأضف كلا الوسمين إليه، واطبع العنوان، واعرض قائمة بجميع الوسوم.

ستتلقى ثلاثة مدخلات:

  1. عنوان المقال (سلسلة نصية)
  2. الوسم الأول المراد إضافته (سلسلة نصية)
  3. الوسم الثاني المراد إضافته (سلسلة نصية)

يجب أن يعرض مخرجك عنوان المقال متبوعاً بوسومه:

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
quiz iconاختبر نفسك

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

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