4. تطوير MVC (النموذج – العرض – وحدة التحكم)
غالبًا ما يكون لتطبيق الويب بنية من 3 طبقات:

- تتولى طبقة [DAO] الوصول إلى البيانات، وغالبًا ما تكون بيانات ثابتة داخل نظام إدارة قواعد البيانات (DBMS). ولكن يمكن أن تكون هذه البيانات أيضًا قادمة من أجهزة الاستشعار أو الشبكة أو غير ذلك.
- تقوم طبقة [الأعمال] بتنفيذ خوارزميات "الأعمال" الخاصة بالتطبيق. هذه الطبقة مستقلة عن أي شكل من أشكال واجهة المستخدم. وبالتالي، يجب أن تكون قابلة للاستخدام مع واجهة وحدة التحكم، أو واجهة الويب، أو واجهة عميل غنية. ولذلك يجب أن تكون قابلة للاختبار خارج واجهة الويب، خاصة مع واجهة وحدة التحكم. هذه هي عمومًا الطبقة الأكثر استقرارًا في البنية. ولا تتغير هذه الطبقة في حالة تغيير واجهة المستخدم أو طريقة الوصول إلى البيانات اللازمة لتشغيل التطبيق.
- طبقة [واجهة المستخدم]، وهي الواجهة (التي غالبًا ما تكون رسومية) التي تتيح للمستخدم التحكم في التطبيق وتلقي المعلومات منه.
يتدفق الاتصال من اليسار إلى اليمين:
- يقدم المستخدم طلبًا إلى طبقة [واجهة المستخدم]
- يتم تنسيق هذا الطلب بواسطة طبقة [واجهة المستخدم] وإرساله إلى طبقة [منطق الأعمال]
- إذا احتاجت طبقة [منطق الأعمال] إلى بيانات لمعالجة هذا الطلب، فإنها تطلبها من طبقة [DAO]
- تقوم كل طبقة يتم الاستعلام عنها بإرجاع استجابتها إلى الطبقة الموجودة على يسارها حتى تصل الاستجابة النهائية إلى المستخدم.
عادةً ما يتم الوصول إلى طبقتي [الأعمال] و[DAO] عبر واجهات Java. وبالتالي، فإن طبقة [الأعمال] لا تعرف سوى واجهة (واجهات) طبقة [DAO] ولا تعلم شيئًا عن الفئات التي تنفذها. وهذا ما يضمن استقلالية الطبقات عن بعضها البعض: لا يؤثر تغيير تنفيذ طبقة [DAO] على طبقة [الأعمال] طالما ظل تعريف واجهة طبقة [DAO] دون تغيير. وينطبق الأمر نفسه بين طبقتي [واجهة المستخدم] و[الأعمال].
يتم تنفيذ بنية MVC (النموذج – العرض – وحدة التحكم) في طبقة [واجهة المستخدم] عندما تكون واجهة ويب:

تتم معالجة طلب العميل وفقًا للخطوات التالية:
- يرسل العميل طلبًا إلى وحدة التحكم. تتولى وحدة التحكم معالجة جميع طلبات العملاء. وهي نقطة الدخول إلى التطبيق. وهي تمثل الحرف C في نموذج MVC.
- تقوم وحدة التحكم C بمعالجة هذا الطلب. وللقيام بذلك، قد تحتاج إلى مساعدة من طبقة الأعمال. وبمجرد معالجة طلب العميل، يمكن أن يؤدي ذلك إلى استجابات متنوعة. ومن الأمثلة الكلاسيكية على ذلك:
- صفحة خطأ إذا تعذر معالجة الطلب بشكل صحيح
- صفحة تأكيد في الحالات الأخرى
- تختار وحدة التحكم الاستجابة (= العرض) التي سيتم إرسالها إلى العميل. يتضمن اختيار الاستجابة التي سيتم إرسالها إلى العميل عدة خطوات:
- اختيار الكائن الذي سيولد الاستجابة. وهذا ما يُسمى العرض V، وهو حرف V في MVC. يعتمد هذا الاختيار عمومًا على نتيجة تنفيذ الإجراء الذي طلبه المستخدم.
- تزويده بالبيانات التي يحتاجها لتوليد هذا الرد. في الواقع، غالبًا ما يحتوي هذا الرد على معلومات يحسبها وحدة التحكم. تشكل هذه المعلومات ما يسمى بنموذج M للعرض، وهو الحرف M في MVC.
- لذلك تتكون الخطوة 3 من اختيار عرض (V) وإنشاء النموذج (M) المطلوب له.
- يُوجه وحدة التحكم C العرض المحدد لعرض نفسه. يتضمن هذا عادةً تنفيذ طريقة محددة للعرض V المسؤولة عن إنشاء الاستجابة للعميل. في هذا المستند، سنشير إلى كل من الكائن الذي ينشئ الاستجابة للعميل والاستجابة نفسها باسم العرض. لا توضح أدبيات MVC هذه النقطة بشكل صريح. إذا كانت الاستجابة هي التي ستُسمى العرض، فيمكننا تسمية الكائن الذي ينشئ هذه الاستجابة بمولد العرض.
- يستخدم مولد العرض V النموذج M الذي أعده وحدة التحكم C لتهيئة الأجزاء الديناميكية من الاستجابة التي يجب إرسالها إلى العميل.
- يتم إرسال الاستجابة إلى العميل. يعتمد شكلها الدقيق على مولد العرض. يمكن أن يكون دفق HTML أو ملف PDF أو Excel، إلخ.
لا تتطلب منهجية تطوير الويب MVC بالضرورة أدوات خارجية. وبالتالي، يمكن تطوير تطبيق ويب Java بهيكلية MVC باستخدام JDK بسيط ومكتبات تطوير ويب أساسية. وفيما يلي طريقة مناسبة للتطبيقات البسيطة:
- يتم التعامل مع وحدة التحكم بواسطة سيرفلت واحد. وهذا هو C في MVC.
- تحتوي جميع طلبات العميل على سمة "action"، على سبيل المثال (http://.../appli?action=liste).
- اعتمادًا على قيمة سمة الإجراء، يقوم السيرفلت بتنفيذ طريقة داخلية من النوع [doAction(...)].
- تقوم طريقة [doAction] بتنفيذ الإجراء الذي طلبه المستخدم. للقيام بذلك، تستخدم طبقة [business] إذا لزم الأمر.
- اعتمادًا على نتيجة التنفيذ، تقرر طريقة [doAction] صفحة JSP التي سيتم عرضها. هذا هو العرض (V) في نموذج MVC.
- تحتوي صفحة JSP على عناصر ديناميكية يجب أن توفرها السيرفلت. ستوفر طريقة [doAction] هذه العناصر. هذا هو نموذج العرض، وهو الحرف M في MVC. غالبًا ما يتم وضع هذا النموذج في سياق الطلب (request.setAttribute("key", "value")، أو، في حالات أقل تكرارًا، في سياق الجلسة أو التطبيق. تتمتع صفحة JSP بإمكانية الوصول إلى هذه السياقات الثلاثة.
- تقوم طريقة [doAction] بعرض الصفحة عن طريق تمرير مسار التنفيذ إلى صفحة JSP المحددة. وللقيام بذلك، تستخدم عبارة مثل [getServletContext() .getRequestDispatcher("صفحة JSP").forward(request, response)].
يُطلق على نمط تصميم MVC هذا اسم نمط "Front Controller" أو نمط وحدة التحكم الواحدة. حيث تتولى وحدة سيرفلت واحدة معالجة جميع الطلبات الواردة من جميع المستخدمين.
لنعد إلى بنية تطبيق الويب السابق:

تتوافق هذه البنية مع بنية n-tier التالية:

في الواقع، هناك طبقة واحدة فقط: طبقة واجهة الويب. بشكل عام، سيكون لتطبيق الويب MVC القائم على السيرفلتات وصفحات JSP البنية التالية:

بالنسبة للتطبيقات البسيطة، هذه البنية كافية. عندما تكتب عدة تطبيقات من هذا النوع، تدرك أن سيرفلتات تطبيقين مختلفين:
- تستخدمان نفس الآلية لتحديد الطريقة [doAction] التي يجب تنفيذها لمعالجة الإجراء المطلوب من قبل المستخدم
- في الواقع لا يختلفان إلا في محتوى طرق [doAction] هذه
ومن ثم، يكون الإغراء قويًا للقيام بما يلي:
- تقسيم المعالجة (1) إلى سيرفلت عام لا يعرف التطبيق الذي يستخدمه
- تفويض المعالجة (2) إلى فئات خارجية نظرًا لأن السيرفلت العام لا يعرف في أي تطبيق يتم استخدامه
- ربط الإجراء المطلوب من قبل المستخدم بالفئة التي يجب أن تعالجه باستخدام ملف تكوين
ظهرت أدوات، غالبًا ما تسمى "أطر عمل"، لتزويد المطورين بهذه القدرات. أقدمها وربما أشهرها هو Struts (http://struts.apache.org/). Jakarta Struts هو مشروع تابع لمؤسسة Apache Software Foundation (www.apache.org). يرد وصف إطار العمل هذا في (http://tahe.developpez.com/java/struts/).
يقدم إطار عمل Spring (http://www.springframework.org/)، الذي ظهر مؤخرًا، ميزات مشابهة لتلك الموجودة في Struts. وقد تم وصف استخدامه في عدة مقالات (http://tahe.developpez.com/java/springmvc-part1/).
نقدم الآن مثالاً على بنية MVC تستند إلى السيرفلتات وصفحات JSP.