معمارية MVC: ما هو إطار Model View Controller وكيف يعمل؟

دقائق القراءة: 7

ما هي معمارية MVC ولماذا تُعد مهمة في تطوير البرمجيات؟

تُعد معمارية Model–View–Controller أو اختصاراً MVC واحدة من أشهر الأنماط المعمارية في تطوير البرمجيات، إذ تُستخدم لفصل منطق التطبيق إلى ثلاثة مكونات رئيسية مستقلة نسبياً. هذا الفصل يساعد المطورين على تنظيم الشيفرة البرمجية، وتسهيل الصيانة، وتحسين قابلية التوسع، خاصة في تطبيقات الويب الحديثة.

الفكرة الجوهرية وراء MVC هي عدم وضع كل شيء في مكان واحد. بدلاً من دمج البيانات وواجهة المستخدم ومنطق التشغيل داخل ملفات متشابكة، يتم توزيع المسؤوليات بوضوح بين Model وView وController. وبهذا يصبح التطبيق أكثر ترتيباً وأسهل في التطوير الجماعي.

صورة توضيحية تعبر عن مفهوم معمارية MVC في تطوير تطبيقات الويب

لمحة تاريخية عن نمط Model–View–Controller

ظهر نمط MVC لأول مرة عام 1979 على يد عالم الحاسوب Trygve Mikkjel Heyerdahl Reenskaug. كان الهدف من هذا النمط هو إيجاد وسيلة فعالة لتقسيم التطبيقات المعقدة إلى أجزاء أصغر وأسهل في الإدارة.

استُخدم هذا النمط في البداية ضمن لغة البرمجة Small Talk. ومن المثير للاهتمام أن الاسم المقترح في البداية كان Model-View-Editor، لكنه تغيّر لاحقاً إلى Model-View-Controller ليعكس دور المكوّن الثالث بشكل أدق.

خلال الثمانينيات وبداية التسعينيات، كان استخدام MVC شائعاً في تطبيقات سطح المكتب. لكن مع صعود الويب في أواخر التسعينيات، بدأ هذا النمط يكتسب شعبية واسعة في تطبيقات الويب، وأصبح اليوم خياراً معمارياً أساسياً في كثير من المشاريع الحديثة.

أشهر الأطر التي تعتمد على MVC

هناك العديد من الأطر البرمجية الشهيرة التي تبنت نمط MVC أو استلهمت مبادئه في تنظيم المشروع، ومن أبرزها:

  • Ruby on Rails
  • ASP.NET MVC
  • Laravel
  • Angular

ورغم أن بعض هذه الأطر قد تطبق MVC بشكل مباشر أو بصيغ قريبة منه، فإن الفكرة الأساسية تبقى واحدة: فصل المسؤوليات لتطوير تطبيقات أكثر وضوحاً وكفاءة.

ما المكونات الثلاثة في معمارية MVC؟

تعتمد معمارية MVC على ثلاثة مكونات رئيسية، لكل منها وظيفة محددة داخل التطبيق:

  • Model: مسؤول عن منطق البيانات والتعامل مع التخزين وقواعد البيانات.
  • View: مسؤول عن عرض البيانات للمستخدم وتمثيل واجهة الاستخدام.
  • Controller: يعمل كحلقة وصل بين Model وView، ويتولى منطق التحكم وسير العمليات.

1) Model: طبقة البيانات والمنطق المرتبط بها

يمثل Model الجزء المسؤول عن بنية البيانات وقواعد التعامل معها. هذه الطبقة لا تهتم بكيفية عرض البيانات للمستخدم، بل تركّز على تخزينها، والتحقق منها، واسترجاعها، وتحديثها.

2) View: طبقة العرض والتفاعل

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

3) Controller: طبقة التنسيق والتحكم

يؤدي Controller دور العقل المنظم للتطبيق، فهو يستقبل الطلبات، ويتواصل مع Model للحصول على البيانات أو تعديلها، ثم يمرر النتائج إلى View لعرضها بالشكل المناسب.

كيف تعمل معمارية MVC في تطبيق ويب عملي؟

لفهم الفكرة بصورة أوضح، من المفيد النظر إلى مثال تطبيقي. في هذا المثال، لدينا تطبيق ويب مبني باستخدام MERN، وهو اختصار لـ MongoDB وExpress وReact وNode.

التطبيق يعرض لوحة معلومات خاصة بمدير مكتب افتراضي، وتحتوي على قائمة بالمدربين الجدد الذين تم تعيينهم مؤخراً في المدارس الثانوية، إلى جانب حالة مستنداتهم المطلوبة.

لوحة معلومات في تطبيق ويب توضح استخدام معمارية MVC لعرض بيانات المدربين

كما يعرض التطبيق المدربين الذين لم يستكملوا بعض المتطلبات مثل TB tests وCovid vaccines وnew coach application وbackground checks.

واجهة تعرض المستندات الناقصة للمدربين ضمن تطبيق يعتمد على MVC

ويمكن لمدير المكتب إرسال رسائل تذكير عبر البريد الإلكتروني إلى المدربين الذين لم يكملوا مستنداتهم.

زر إرسال رسائل تذكير عبر البريد الإلكتروني داخل تطبيق MVC

مكوّن Model في التطبيق العملي

في هذا التطبيق، يتولى Model مسؤولية التعامل مع بيانات المدربين. وقد استُخدمت قاعدة بيانات MongoDB لتخزين المعلومات، مع تعريف مخطط Schema يحدد خصائص كل مدرب داخل قاعدة البيانات.

يتضمن كل سجل حقولاً مثل name وemail وprogram، بالإضافة إلى حقول منطقية من النوع Boolean لتحديد ما إذا كان المدرب قد أكمل بعض المتطلبات.

const coachSchema = new Schema({
  name : {
    type : String,
    trim : true,
    maxLength : 32,
    required : true
  },
  email : {
    type : String,
    trim : true,
    maxLength : 32,
    required : true,
    unique : true
  },
  program : {
    type : String,
    trim : true,
    maxLength : 32,
    required : true
  },
  application : {
    type : Boolean,
    required : true
  },
  backgroundCheck : {
    type : Boolean,
    required : true
  },
  tbTest : {
    type : Boolean,
    required : true
  },
  covidTest : {
    type : Boolean,
    required : true
  }
}, { timestamps : true })

القيم من النوع Boolean تعبّر عن حالتين فقط: true أو false. وإذا كانت أي من الخصائص application أو backgroundCheck أو tbTest أو covidTest تحمل القيمة false، فهذا يعني أن المدرب لم يستكمل ذلك الجزء من الإجراءات المطلوبة.

تم إنشاء عدة سجلات داخل قاعدة البيانات وتخزينها في MongoDB Atlas. ويُعد هذا مثالاً عملياً واضحاً على دور Model بوصفه المصدر الأساسي للبيانات في التطبيق.

مثال على سجل بيانات داخل MongoDB Atlas ضمن تطبيق يستخدم MVC

بعد ذلك، يتواصل Controller مع قاعدة البيانات للحصول على المعلومات المطلوبة وتمريرها إلى View.

مكوّن View في التطبيق العملي

يتولى View مسؤولية الجوانب المرئية في التطبيق. في هذا المثال، تم استخدام React لعرض البيانات للمستخدم بطريقة تفاعلية ومنظمة.

عند تشغيل التطبيق للمرة الأولى، تظهر رسالة ترحيبية على الشاشة.

رسالة ترحيب في واجهة React ضمن تطبيق يعتمد على بنية MVC

وعند النقر على زر View Dashboard، ينتقل المستخدم إلى لوحة تعرض جدول المدربين وقائمة المستندات الناقصة. من المهم هنا ملاحظة أن View لا تتصل مباشرة بقاعدة البيانات، بل تحصل على المعلومات عبر Controller.

جدول المدربين داخل واجهة React يعرض بيانات قادمة من Controller

يظهر ذلك بوضوح في استدعاء fetch من الواجهة للحصول على البيانات من Controller:

await fetch('https://mvc-project-backend.herokuapp.com/coaches')

بعد استرجاع البيانات، يتم استخدام الدالة map() للمرور على عناصر القائمة وعرض بيانات كل مدرب داخل الجدول.

coachData.map(data => (
  <tr key={data._id}>
    <td>{data.name}</td>
    <td>{data.email}</td>
    <td>{data.program}</td>
  </tr>
))

وبالنسبة لقسم المستندات الناقصة، يتم جلب البيانات من backend ثم استخدام map() مرة أخرى لعرض أسماء المدربين ضمن كل فئة من الفئات المطلوبة.

عرض أسماء المدربين الذين تنقصهم مستندات باستخدام React في بنية MVC

وعند النقر على زر Send reminder email، تُرسل البيانات من React إلى backend. بعد ذلك يتولى Controller عملية إرسال البريد وإرجاع حالة التنفيذ إلى View، التي تعرض للمستخدم رسالة نجاح أو فشل حسب النتيجة.

رسالة نجاح في واجهة التطبيق بعد إرسال بريد إلكتروني عبر Controllerرسالة فشل أو خطأ في واجهة المستخدم عند تعذر إرسال البريد الإلكتروني

مكوّن Controller في التطبيق العملي

يُعد Controller الجزء الذي يربط بين Model وView ويتولى معظم منطق التطبيق. في هذا المثال، تم بناء هذه الطبقة باستخدام Node.JS وExpress.

تتلخص مهام Controller في عدة نقاط أساسية:

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

في ميزة البريد الإلكتروني، يتحقق Controller أولاً من صلاحية البريد الإلكتروني للمرسل، ثم يستخدم Nodemailer لتنفيذ عملية الإرسال.

transporter.sendMail(mailOptions, (err) => {
  if (err) {
    console.log(`Applications: There was an error sending the message: ${err}`)
    res.json({ status : 'Email failure' })
  } else {
    console.log(`Applications Success: Email was sent`)
    res.json({ status : 'Email sent' });
  }
})

إذا نجحت العملية، يتم إشعار المستخدم بذلك، كما تظهر الرسالة في حساب البريد الإلكتروني التجريبي المستخدم في التطبيق.

ظهور رسالة البريد الإلكتروني المرسلة بنجاح في الحساب التجريبي باستخدام Nodemailer

أما في حال حدوث خطأ أثناء الإرسال، فإن Controller يعيد النتيجة إلى View، لتعرض رسالة الخطأ المناسبة للمستخدم بشكل واضح.

لماذا تساعد معمارية MVC في بناء تطبيقات أفضل؟

الاعتماد على MVC Architecture لا يمنح المشروع مجرد هيكل منظم فحسب، بل يقدم أيضاً فوائد عملية مهمة، من أبرزها:

  • سهولة الصيانة: لأن كل جزء من التطبيق يؤدي وظيفة محددة بوضوح.
  • تحسين قابلية التوسع: يمكن تطوير كل طبقة أو تعديلها دون التأثير الكبير على الطبقات الأخرى.
  • العمل الجماعي بكفاءة: يمكن لفريق الواجهة الأمامية التركيز على View، بينما يعمل فريق backend على Model وController.
  • اختبار أسهل: فصل المنطق عن العرض يجعل اختبار الوظائف أكثر دقة وتنظيماً.
  • تنظيم الشيفرة: يقلل من الفوضى البرمجية ويزيد من وضوح المشروع على المدى الطويل.

متى يكون استخدام MVC خياراً مناسباً؟

يُعد MVC مناسباً بشكل خاص عندما يكون التطبيق:

  1. يحتوي على بيانات كثيرة تحتاج إلى إدارة منظمة.
  2. يتضمن واجهات استخدام تفاعلية ومتعددة.
  3. مرشحاً للتوسع مستقبلاً.
  4. يُطوَّر من قِبل أكثر من مطور أو فريق.
  5. يحتاج إلى بنية واضحة تفصل بين الواجهة ومنطق الأعمال والبيانات.

أما في التطبيقات الصغيرة جداً، فقد تبدو هذه المعمارية أكبر من الحاجة، لكن قيمتها الحقيقية تظهر مع ازدياد حجم المشروع وتعقيده.

الخلاصة التقنية

تمثل Model–View–Controller واحدة من أكثر المعماريات نضجاً وفعالية في تطوير البرمجيات، لأنها تفرض فصلاً صحياً بين البيانات والعرض والتحكم. عملياً، هذا الفصل لا يحسن تنظيم الشيفرة فقط، بل ينعكس مباشرة على سرعة التطوير، وسهولة الصيانة، وقابلية التوسع. وإذا كنت تبني تطبيق ويب متوسطاً أو كبيراً، فإن فهم MVC وتطبيقه بشكل صحيح يمنحك أساساً هندسياً قوياً يختصر كثيراً من التعقيد مستقبلاً.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *