تطبيق Mixins متعددة
جزء من قسم البرمجة كائنية التوجه في رحلة Lua على Coddy. الدرس 52 من 70.
يضيف المزيج الواحد مجموعةً من السلوكيات إلى صنف. لكن الكائنات الحقيقية غالبًا ما تحتاج إلى إمكانات من مصادر متعددة. قد يحتاج كائن لعبة إلى التحرك والظهور على الشاشة: وهما مجالان منفصلان لا ينتميان إلى المزيج نفسه.
الحل بسيط: طبّق عدة خلطات على الفئة نفسها. تضيف كل خلطة أساليبها الخاصة، وتنتهي الفئة بامتلاكها جميعًا:
local Movable = {}
function Movable:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
local Visible = {}
function Visible:show()
print("Showing at " .. self.x .. ", " .. self.y)
end
function Visible:hide()
print("Hidden")
endطبّق كلا المزيجين على صفك باستخدام دالة المساعدة نفسها التي استخدمتها من قبل:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local GameObject = {}
GameObject.__index = GameObject
applyMixin(GameObject, Movable)
applyMixin(GameObject, Visible)يمكن الآن لكائنات GameObject أن تتحرك وتعرض نفسها:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- العرض عند 5, 3تنبيه واحد: إذا عرّف خليطان الاسم نفسه لطريقة، فسيحلّ الثاني الذي يُطبَّق محلّ الأول. اجعل طرق الخليطات متميزة لتجنّب السلوك غير المتوقع.
التحدي
سهللننشئ صنف Character للعبة يجمع إمكانات متعددة باستخدام المزجيات! ستتمكن شخصيتك من مهاجمة الأعداء ومعالجة نفسها: سلوكان متميزان يأتيان من مزجيين منفصلين.
ستنظم الشيفرة عبر أربعة ملفات:
Attacker.lua: أنشئ مزيجًا يتضمن طريقة:attack(targetName)تطبع{self.name} attacks {targetName} for {self.damage} damage!(يفترض أن الكائن لديه الحقلانnameوdamage)Healer.lua: أنشئ مزيجًا يتضمن طريقة:heal(amount)تضيف المقدار إلىself.healthوتطبع{self.name} heals for {amount}. Health: {newHealth}Character.lua: أنشئ صنف Character بمنشئ:new(name, health, damage)يخزّن السمات الثلاث كلها. طبّق مزيجي Attacker وHealer كي تتمكن كل شخصية من الهجوم والمعالجة. أضف طريقة:status()تطبع{name} - Health: {health}, Damage: {damage}main.lua: اكتب الدالة المساعدةapplyMixinهنا. اقرأ مدخلات اسم الشخصية وصحتها وقيمة الضرر واسم الهدف المراد مهاجمته ومقدار المعالجة. أنشئ شخصية، واعرض حالتها، واجعلها تهاجم الهدف وتعالج نفسها، ثم اعرض حالتها مجددًا.
ستتلقى خمسة مدخلات:
- اسم الشخصية (سلسلة نصية)
- الصحة عند البدء (عدد)
- قيمة الضرر (عدد)
- اسم الهدف المراد مهاجمته (سلسلة نصية)
- مقدار المعالجة (عدد)
يجب أن يُظهر الناتج استخدام الشخصية لقدرتَي المزيجين:
{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}على سبيل المثال، إذا كانت المدخلات هي Warrior و100 و25 وGoblin و30، فيجب أن يكون الناتج:
Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25يسهم كل مزيج بطريقته الخاصة في صنف Character. لا ترث الشخصية من أيٍّ من المزيجين، بل تكتسب قدراتهما ببساطة عبر الدالة applyMixin. هذه هي قوة الجمع بين عدة مزجيات!
جرّب بنفسك
-- الملف الرئيسي
-- TODO: اكتب الدالة المساعدة applyMixin
-- يجب أن تنسخ هذه الدالة جميع الأساليب من جدول mixin إلى جدول هدف
local function applyMixin(target, mixin)
-- TODO: نفّذ تطبيق mixin
end
-- اجعل applyMixin متاحةً على المستوى العام ليتمكن Character.lua من استخدامها
_G.applyMixin = applyMixin
local Character = require('Character')
-- اقرأ المدخلات
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())
-- TODO: أنشئ Character بالاسم والصحة والضرر المحددة
-- TODO: اعرض حالة الشخصية
-- TODO: اجعل الشخصية تهاجم الهدف
-- TODO: اجعل الشخصية تعالج نفسها
-- TODO: اعرض حالة الشخصية مرة أخرى
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
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 مقابل الوراثةملخص - تجميع الروبوتتدرّب بنفسك: مترجم Lua عبر الإنترنت