Shagrouni

تطبيق UML ـ التحليل و التصميم الكائني باستخدام UML

ترجمة:خالد الشقروني

محتويات

الفصل الثالث
المنحى للكائن

 الفصل 3
المنحى للكائن


في هذا الفصل سوف نلقي نظرة على مفهوم المنحى للكائن Object Orientation 4 (OO) . لقد تمّ تصميم لغة النمذجة الموحّدة UML بحيث تدعم المنحى للكائن ، لذلك سنقوم بتعريف مفاهيمه قبل التعمق في لغة UML ، و استكشاف المزايا التي قد يوفرّها.

البرمجة المهيكلة

أولا، لنختبر بصورة سريعة كيف يتم تصميم الأنظمة البرمجية باستخدام الاتجاه المهيكل (احيانا يُسمّى وظائفي Functional).

في البرمجة المهيكلة Structured Programming، الطريقة المتّبعة عامة هي النظر الى المسألة، ثم تصميم مجموعة من الوظيفيات functions التي يمكنها انجاز المهام المطلوبة لحلها. اذا تضخّمت هذه الوظيفيات ، يتم تجزئتها حتى تصير صغيرة بالحدّ الذي يتيسّر فيه مناولتها و فهمها. هذه العملية تدعى التفكيك الوظائفي functional decomposition.

معظم الوظيفيات ستحتاج الى بيانات من نوع ما لتعمل عليها. البيانات في الأنظمة الوظائفية عادة ما يحتفظ بها في قاعدة بيانات من نوع ما (أو قد يحتفظ بها في الذاكرة كمتغيّرات شاملة global variables) .

لنأخذ مثالا بسيطا، تخيّل منظومة لإدارة معهد، هذه المنظومة تحتفظ ببيانات الطلبة و المدرّبين في المعهد اضافة للمعلومات حول الدورات المتوفرة، كذلك تقوم المنظومة بتتبع كل طالب و الفصول التي التحق بها.

التصميم الوظائفي المحتمل سيتضمّن كتابة الوظيفيات functions التالية:

اضافة طالب

add_student 5

دخول امتحان

enter_for_exam

فحص علامات امتحان

check_exam_marks

اصدار شهادة

issue_certificate

طرد طالب

expel_student

سوف نحتاج ايضا الى نموذج بيانات data model ليمثّل هذه الوظيفيات. نحتاج لتخزين معلومات عن الطلبة ، و المدربين و الامتحانات و الدورات، لذا يجب علينا تصميم مخطط قاعدة بيانات database schema للاحتفاظ بهذه البيانات. 6

قاعدة بيانات تحتوي على اربع جداول (Tables)


شكل 9: مخطط قاعدة بيانات بسيط. الخطوط المنقطّة تشير الى اعتمادية مصفوفة بيانات على أخرى، مثلا، كل طالب يتم تدريبه بواسطة عدة مدرّبين.

الآن بدأ واضحا أن الوظيفيات functions التي حدّدناها سابقا سوف تعتمد على هذه المصفوفة من البيانات. مثلا، وظيفة "add_student" (اضافة طالب) ستقوم بتغيير محتويات  "Students" (طلبة)، و وظيفة "issue_certificate" (اصدار شهادة) تحتاج الى الوصول الى بيانات طالب Student (لمعرفة تفاصيل الطالب الذي يحتاج للشهادة) و ستحتاج الوظيفة ايضا الي بيانات الامتحانات Exam .

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


شكل 10: خريطة الوظائف، و البيانات و الاعتماديات.

المشكلة مع هذه المقاربة أن المسألة التي نتعامل معها اذا ما تعقدت أكثر ستزداد صعوبة المحافظة على المنظومة و صيانتها. فلو اخذنا المثال أعلاه، ماذا سيحدث لو تغيّرت المتطلبات requirement  بطريقة تؤدّي الى تغيير اسلوب مناولة بيانات الطالب Student.

كمثال، لنتخيّل ان منظومتنا تعمل على أكمل ما يكون، لكننا اكتشفنا ان تخزين تاريخ ميلاد الطالب على شكل عدد ذو خانتين كي يمثل السنة كانت فكرة سيّئة، الحل المبدئ هنا هو ان نقوم بتغيير حقل تاريخ الميلاد في جدول الطلبة Students من خانتين الى اربع خانات لرقم السنة.

المشكلة الجدية لهذا التغيير تنبع من أنه قد يسبّب في ظهور اثار جانبية غير متوقعة. فبيانات جدول الامتحانات Exam و جدول الدورات Courses و جدول المدرّبين Tutors كلها (بطريقة أو باخرى) تعتمد على بيانات جدول الطالب Students، لذا قد نتسبب في كسر بعض العمليات بتغييرنا البسيط هذا، و اعاقة  وظيفيات add_student و enter_for_exams و issue_certificate و expel_student ، فوظيفة add_student لن تعمل بالتأكيد لأنها تتوقع ان تكون المعلومة الخاصة بسنة الميلاد على شكل رقم بخانتين بدلا من أربع.

 اذا، لدينا معدل كبير من المشاكل المحتملة، و الأسوأ اننا لن نستطيع بسهولة تعيين اماكن الاعتمادية في التوليف code التي ستتأثر بهذا التغيير.

 كم من مرّة قمت بتعديل سطر في التوليف و بكل براءة دون أن تعي انك سبّبت عن غير قصد في كسر عمليات اخرى قد تبدو لا علاقة لها في الظاهر؟

اشكالية عام 2000 (ثغرة الألفية) ذات التكلفة العالية كان سببها بالضبط هذه المشكلة. فحتى لو ان حلها يفترض به ان يكون بسيطا (تغيير كل حقل سنة من خانتين الى اربع) فان التداعيات المحتملة لهذا التغيير البسيط يجب التحقق منها و فحصها بدقة. 7

أسلوب المنحى للكائن

المنحى للكائن "OO" يحاول التقليل من تأثير هذه المشكلة و ببساطة عن طريق الجمع بين البيانات data و الوظيفيات functions ذات العلاقة في قالب module واحد.

بالنظر الى الشكل 10 أعلاه، يبدو واضحا وجود علاقة بين البيانات و الوظيفيات؛ فمثلا و ظيفتي: add_student و expel_student  مرتبطتان بقوة ببيانات Student الطالب.

الشكل التالي يبيّن التجميعات الكلّية للبيانات و الوظيفيات ذات العلاقة على شكل قوالب:


شكل 11: البيانات و الوظيفيات المرتبطة موضوعة في قوالب.

   بعض النقاط الجديرة بالملاحظة حول نظام القولبة الجديد في البرمجة:

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

  • القوالب يمكنها "التخاطب" مع قوالب اخرى عن طريق استدعاء وظيفياتها.

التغليف

Encapsulation

 الأمر الأساسي هنا، أنه لا يتم السماح بقراءة أو تغيير أي عنصر في البيانات إلا من للتمثل الذي تتبعها . فمثلا، التمثل الخاص بقالب المدرّب Tutor لا يمكنه تحديث او قراءة بيانات "age"  العمر داخل قالب Student الطالب.

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

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

الكائنات

Objects

خلال هذا الفصل، أشرنا الى هذه التوليفات من البيانات و الوظيفيات المرتبطة بأنها قوالب "modules". عموما اذا نظرنا الى خصائص هذه القوالب سنجد مرادفات لها في العالم الحقيقي.

الكائنات Objects  في عالم الواقع يمكن تمييزها بشيئين : كل كائن في عالم الواقع لديه بيانات data و سلوك behaviour . فمثلا جهاز التلفاز هو كائن و يعالج بيانات بطريقة تجعلها تتضبط من خلال قناة محددة، معدّل المسح يتم تحديده الى قيمة معيّنة، كذلك معدّل التباين و شدّة الاضاءة و هكذا. التلفاز ايضا يمكنه "يقوم" بأشياء، التلفاز يمكنه التشغيل او الاقفال، القنوات يمكن تغييرها، و هكذا.

يمكننا تمثيل هذه المعلومات بنفس اسلوب القوالب الببرمجية السابقة:


شكل 12: بيانات و سلوك جهاز التلفاز

على المنوال نفسه اذا، فان "كائنات" العالم الحقيقي بالامكان قولبتها بطريقة مشابهة للقوالب البرمجية التي سبق مناقشتها.

لهذا السبب، نسمّي هذه القوالب بالكائنات Objects و منها جاء مصطلح البرمجة / التصميم  بالمنحى للكائن Object Oriented Design/Programming.

حيث أن نظمنا البرمجية تقدّم حلولا لمشاكل حقيقية في واقعنا (سواء كان ذلك نظام تسجيل في معهد، او نظام ادارة مخازن ، أو نظام توجيه صواريخ)، يمكننا تحديد الكائنات في العالم الواقعي و بسهولة نقوم بتحويلها الى كائنات برمجية.

بكلمات أخرى، المنحى للكائن يقدم تجريدا أو تمثيلا افضل الواقع. نظريا، هذا يعني أنه اذا تغيّر الواقع (كتغيّر المتطلبات) فان تغيير الحلول أو تعديلها ستكون أسهلا ما دامت الخطوط مابين مشاكل الواقع و الحلول الموضوع لها أسهل.

مصطلحات

البيانات data الخاصة بالكائن object تسمّى عادة بخصائص أو سمات Attributes الكائن. التصرّفات المختلفة التي يقوم بها الكائن تسمّى مسالك أو نهجيات Methods الكائن. المسالك هي مرادف لما يعرف في لغات البرمجة بالوظيفيات functions او الاجرائيات procedures .

المصطلح الآخر المشهور في هذا السياق هو Class الصنف. الصنف هو ببساطة أرضية (template) يقوم عليها الكائن. يتم في الصنف وصف السمات attributes و المسالك methods التي ستكون حاضرة لكل تجسّدات الصنف. في منظومة المعهد التي تكلّمنا عنها في هذا الفصل، كان لدينا صنفا يسمّى Student.

سمات attributes صنف الطالب Student Class كانت الاسم و العمر و ما الى ذلك، أما المسلكيات methods فكانت add و expel. في التوليف code سنحتاج لتحديد هذا الصنف لمرة واحدة فقط. و حالما يتم تشغيل التوليف ، يمكننا انشاء create تجسّدات instances هذا الصنف أو بعبارة أخرى: انشاء كائنات objects الصنف.

كل كائن منها سيمثل طالبا، و كل منها ايضا سيحوي ما يخصّه من قيم البيانات.

استراتجية المنحى للكائن

  بالرغم من أن هذا الفصل قد لمس باختصار فوائد المنحى للكائن (مثل: منظومات أكثر ثباتا، تمثيل أفضل للواقع)، إلا أننا تركنا بعض الأسئلة بدون اجابة. كيف نميّز الكائنات التي نحتاجها عند تصميمنا لمنظومة ما؟ ما هي المسلكيات methods و السمات attributes المفترض وجودها؟ ما هو الحجم المناسب للصنف؟ و غيرها من الأسئلة. ستنتقل بنا هذه الدروس خلال عمليات تنشئة البرمجيات باستخدام المنحى للكائن (و UML) ، و سنقوم بالاجابة على كل هذه الأسئلة.

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

الاتجاه الحديث و المدعوم بقوة من قبل UML هو نسيان كلّ ما يتعلّق بالكائنات و الأصناف في المراحل المبكّرة للمشروع، و التركيز بدل ذلك على ما يجب أن تكون المنظومة قادرة على القيام به. بعد ذلك، و مع تقدّم العمل في المشروع يتم تدريجيا بناء الأصناف لتجسيد النواحي الوظيفية للمنظومة المطلوبة.  في هذه الدروس سنتتّبع هذه الخطوات بدءاً من التحاليل الأوّلية و حتى تصميم الصنف.

موجز

  • المنحى للكائن طريقة تفكير تختلف عن الاتجاه المهيكل.

  • نقوم بالجمع بين البيانات و التصرفات ذات العلاقة داخل أصناف.

  • ثم يقوم برنامجنا بانشاء تجسّدات للصّنف، بشكل كائنات.

  • الكائنات يمكنها التعاون مع بعضها البعض، من خلال مخاطبة مسلكياتها.

  • البيانات في الكائن مغلّفة و لا يقوم بتعديلها إلا الكائن نفسه.

 


4 سوف استعمل جملة المنحى للكائن للتعبير عن التصميم بالمنحى للكائن أو/و البرمجة بالمنحى للكائن.
5 نستخدم الشرطة السفلية "_" للدلالة على ان هذه الوظيفيات مكتوبة داخل توليف code.
6 لاحظ انه خلال هذه الفصل، سوف لن نستعمل صيغة الترميز notation الرسمية للتعبير عن المفاهيم.
7 هذا لا يعني ان المنظومات بلغة كوبول و التي هي ليست ذات منحى كائني كلها منظومات عقيمة. ما أود قوله هو انه لا يوجد أي عيب في البرمجة المهيكلة النمطية، و لكن و جهة نظري في هذا الفصل هو ان المنحى للكائن يوّفر سبيلا لبناء برمجيات اكثر متانة كلما كبرت و تشابكت.

 


 

 

Shagrouni 2002 Khaled Shagrouni  khaled@shagrouni.com