**تبديد ديناميكي مفهوم**
Dynamic Dispatch Demystified

Dynamic Dispatch Demystified: شرح مبسط للإرسال الديناميكي

الإرسال الديناميكي (Dynamic Dispatch) هو آلية أساسية في البرمجة الشيئية (Object-Oriented Programming) تسمح بتحديد الطريقة (Method) التي سيتم استدعاؤها في وقت التشغيل (Runtime) بناءً على النوع الفعلي (Actual Type) للكائن، وليس النوع المعلن عنه (Declared Type). قد يبدو هذا المفهوم معقداً للوهلة الأولى، لكن فهمه يفتح الأبواب لفهم أعمق لكيفية عمل تعدد الأشكال (Polymorphism) وكيفية كتابة أكواد أكثر مرونة وقابلية للتوسع.

بعبارة أخرى، تخيل أن لديك فئة أساسية (Base Class) تسمى "شكل" (Shape) ولديها طريقة اسمها "ارسم" (draw). ثم لديك فئتان مشتقتان (Derived Classes) من "شكل": "دائرة" (Circle) و "مربع" (Square). كلتا الفئتين المشتقتين تعيدان تعريف (Override) طريقة "ارسم" الخاصة بالفئة الأساسية. عندما يكون لديك متغير من نوع "شكل" يشير إلى كائن من نوع "دائرة"، سيتم استدعاء طريقة "ارسم" الخاصة بـ "دائرة" عند استدعاء "شكل.ارسم". هذا هو الإرسال الديناميكي في جوهره.

لماذا نستخدم الإرسال الديناميكي؟

الإرسال الديناميكي يوفر لنا العديد من المزايا:

  • المرونة: يسمح لنا بالتعامل مع الكائنات المختلفة بطريقة موحدة، بغض النظر عن نوعها الفعلي.
  • القابلية للتوسع: يمكننا إضافة فئات جديدة دون الحاجة إلى تعديل الكود الموجود. طالما أن الفئة الجديدة ترث من الفئة الأساسية وتنفذ الطرق المطلوبة، فإن الكود الموجود سيعمل معها بشكل صحيح.
  • تعدد الأشكال: يعتبر الإرسال الديناميكي أساس تعدد الأشكال، وهو مفهوم يسمح لنا بالتعامل مع الكائنات المختلفة كأنها كائنات من نوع واحد.

كيف يعمل الإرسال الديناميكي؟

تعتمد آلية عمل الإرسال الديناميكي على جدول البحث (Lookup Table) الذي يحتفظ به المترجم (Compiler) أو المترجم الفوري (Interpreter) لكل فئة. عند استدعاء طريقة على كائن، يقوم المترجم أو المترجم الفوري بالبحث في جدول البحث الخاص بنوع الكائن الفعلي عن عنوان الذاكرة الخاص بتلك الطريقة. ثم يتم استدعاء الطريقة الموجودة في هذا العنوان.

هناك نوعان رئيسيان من الإرسال:

  • الإرسال الثابت (Static Dispatch): يتم تحديد الطريقة التي سيتم استدعاؤها في وقت الترجمة (Compile Time). هذا النوع من الإرسال أسرع، لكنه أقل مرونة.
  • الإرسال الديناميكي (Dynamic Dispatch): يتم تحديد الطريقة التي سيتم استدعاؤها في وقت التشغيل (Runtime). هذا النوع من الإرسال أبطأ، لكنه أكثر مرونة.

مثال توضيحي

لتوضيح الفكرة، تخيل أن لديك الكود التالي (مثال مبسط بلغة افتراضية):


class Shape {
  method draw() {
    print "Drawing a Shape";
  }
}

class Circle extends Shape {
  method draw() {