مقدمة عن الـ Design pattern
اهلا وسهلا بكم احبائي في الدرس الاول من الـ Design Pattern - مقدمة
في هذه الدورة ان شاء لله سوف نتعلم انواع الـ Design Pattern
مفهوم الـ Design Pattern
هي حلول لبعض المشاكل الشائعة في البرامج ..بمعنى ان هناك مشاكل قد تحدث عند عملك لشئ معين في البرمجة ولكي تتجنب هذه المشاكل يفضل تطبيق احدى طرق الـ Design Pattern وهذه الحلول اثبتت فاعليتها حيث تم تجربتها من خلال مبرمجين سابقين وتم الاتفاق على ان هذه الـ الطرق هي الحلول المناسبة لمثل هذه المشاكل .
انواع الـ Design Pattern
- CREATIONAL PATTERNS
- STRUCTURAL PATTERNS
- BEHAVIORAL PATTERNS
- CREATIONAL PATTERNS : تتعامل مع الطريقة التي تنشئ به الـ OBJECT او ماهو الاسلوب الامثل او انشاء افضل طريقة تتطلب انشاؤه فمثلا اذا اردت انشئ OBJECT من كلاس معين واريد ان استفيد من هذا الكلاس على مستوى النظام كله بمعنى امكانية الاستفادة من هذه المتغيرات في هذه الكلاس في النظام كاملا ولو تم التحديث مثلا على اي تغيير في هذه المتغيرات في الكلاس يؤثر مره واحدة على النظام كله ..
ببساطه : ماهي الطريقة الانسب لانشاء OBJECT معين .
- STRUCTURAL PATTERNS : اي كيف يمكننا عمل اكثر من OBJECT بحيث توجد علاقات مع بعضها بمعنى انه اذا وجد معي اكثر من كلاس . كيف يمكنني ان اجد طريقة لتكوين علاقات بين هذه الكلاسات من اجل تطوير العمل البرمجي والاستفادة من هذه العلاقات بين الكلاسات .
- BEHAVIORAL PATTERNS : اي كيفية عمل الكلاس بناء على شرط معين او طريقة معينة بمعنى كيف ستعمل التعليمة البرمجية بناء على شرط معين
Creational Pattern : وكما قلنا هي تركز على افضل الطرق المناسبة لا انشاء الـ Object
سوف نبدأ عن تعريف الطريقة الاولى وهي الـ Singleton
مفهوم الـ Singleton
يمعنى ان يكون لدينا نسخة واحدة فقط من الـ Object الذي تمثل الكلاس وهي النسخة يتم تكوينها في الذاكرة (Memory) .وتجعلنا نتعامل مع Object واحد فقط من هذا الكلاس في كل النظام
وهذه الطريقة ستجعل مساحة الذاكرة قليلة بالاضافة انك ستجعل اي تعديل يتم من مكان واحد فقط
للتوضيح اكثر . لناخذ هذا التطبيق العملي
لو معنا هذا الكلاس المسمى counter فيه متغير اعطيناه القيمة 0 وايضا فيه دالة تسمى add One وظيفتها زيادة هذا المتغير عندما نقوم باستدعاؤه في كل مرة
في الصورة اعلاه قمنا بعمل نسخة من Object 1 وايضا قمنا بعمل نسخة من Object 2 ومن خلال الـ Object قمنا باستداعاء الدالة Add One وقمنا بتشغيل النظام وكانت الطباعة كتالي :
لاحظ ان تم تكون تكرار النسخة مرتان في الذاكرة ويتم العدد بشكل منفصل .. ونحن لا نريد ذلك . نريد ان يتم العدد على الـ instance مرة واحدة فقط ..
اذن يجب التعديل على المثال حتى يحقق مبدأ الـ Single Tone .
كيف يتم حل مثل هذه المشكلة ؟
يتم حل المشكلة بالاتي : سوف نمنع عمل object اي عمل instance جديد من الـ Object اي نمنع عمل مثل هذا
- عمل Private Object من نفس نوع الكلاس نسميها مثلا Instance
- عمل دالة من النوع public وتكون من النوع static وهذه الدالة تعيد المتغير المسمى INSTANCE . من اجل استدعاؤها من اي مكان .
هذا يعني انه عندما نطلب نسخة من الكلاس يجب ان نستدعي الدالة Get Instance وهذه الدالة سوف تعيد الـ Object المسمى Instance
وبالتي سوف يصبح التعديل على الدالة Main كتالي :
عندما البرنامج يشتغل لاول مرة .. سوف يتم نسخة من الكلاس المسمى Counter حتى ان لم نستدعيه من اي مكان اخر .. وسوف يتم تخزين النسخة في الذاكرة Memory .. الان ماهو الحل لتحسين الاداء Performance . هنا سوف نعمل شيئان لعمل ذلك
- نجعل قمية المتغير المسمى instance يساوي صفر
- نعمل شرط اذا كان قيمة المتغير instance يساوي Null اذن انشئ نسخة جديدة في الذاكرة واذا كانت لا تساوي Null لا تعمل نسخة .
هذه الطريقة اذا تمت سوف يتم التحسين فقط بعمل الشرط وهذه الطريقة تسمى Lazy Initialization بمعنى اننا اجلنا عمل النسخة في الذاكرة الى حين استدعاء من قبل اي كود .. اي لايتم انشاء النسخة إلا اذا احتجنا الى عمل النسخة .. فقط من اجل التحسين للذاكرة .
علاقة الـ Single Tone بـ Single Thread
قبل ان نذكر العلاقة يجب ان نفهم ماذا نقصد بـ Single Thread .. لنوضح ذلك بالصورة التالية :
لو طبقنا المثال اعلى في الدالة Main ولو تخيلنا ان معانا كود او مجموعة من الاكواد كما هو واضح في الطرف الايسر من الصورة وهذا الكود يسير بمسار معين الى المعالج ليتم معالجته .. اذن هذا يسمى الـ Single Thread هنا المعالج سوف يعالج الاكواد تباعا وفقا لترتيب معين مثلا ( التعليمة الاولى ثم التعليمة الثانية ثم التعليمية الثالثة وهكذا .
الان لو طبقنا مبدأ الـ Single Tone على Single Thread يعني لو استدعينا الدالة Get Instance بكتابة الكود التالي في الدالة Main كتالي :
Counter object1=Counter.getInstance()
object1.addOne()
هنا الكود سوف يكون نسخة في الذاكرة .. حيث ان هذه الكود سوف يمر عبر الخط الموضح بالرسم وسيصل الى المعالج ويكون نسخة في الذاكرة . وهي count =1
الان لو قمنا باستدعاء الكود مرة ثانية بكتابة التالية
Counter Object2=Counter.getInstance()
Object2=Counter.getInstance()
هنا الكود سوف يفحص هل هناك نسخة في الذاكرة .. وسوف يجد نسخة ولن ينشئ نسخة جديدة بل سوف يتعامل مع النسخة الموجودة بزيادة العدد الى 2 اي يصبح الـ count =2
بمعنى انه ليست هناك مشكلة في تطبيق مبدأ الـ Single Tone على قاعدة الـ Single Thread .
علاقة الـ Single Tone بـ Multi Thread
للتوضح بالصورة
هنا التعليمات البرمجية سوف تسير باكثر من مسار وبشكل متزامن الى المعالج لكي يتم تفيذها جميعها في وقت واحد
الان لو طبقنا الكود المكتوب في الدالة الـ Main يعني ان كلا من Objec1 , Objec2 سوف يمران بشكل متزامن عبر اكثر من مسار حتى يصلان كلاهما الى المعالج وفي وقت واحد .. تخيل معي كلا منهما يصلان في وقت واحد ليكون كلا منهما نسخة في الذاكرة .. وهذا يعني انهما سوف يكون نسختان في الذاكرة .. وهذا يتعارض مع مبدأ الـ Single Tone
اذن لو طبقنا المثال كما هو في دالة الـ Main . فهذا يعارض مبدأ الـ Single Tone
فما هو الحل ؟ هل هناك طريقة لحل هذه المشكلة ؟ الاجابة نعم
هناك طريقة باستخدام دالة تسمى Lock وهذه الدالة عبارة عن دالة شرطية وضيفتها منع الـ Thread الاخر من التنفيذ قبل ان يتم تنفيذ الـ Thread الاول الموجودة فيها اي في دالة الـ Lock...
وايضا سوف نقوم بالتعديل الى الكود الموجود في الدالة main كتالي
كما هو واضح في الصورة اننا معنا مساران وسوف يمران في اكثر من مسار وسوف يصلان في وقت واحد .. لكن حتى يتحقق مبدأ الـ single tone لابد من اضافة الدالة Lock في الكلاس المسمى counter وبالتحديد على الدالة المسمى GetInstance لاحظ معي الصورة التالية :
لاحظ معي في الصورة اعلاه اضفنا رقم (1) عرفنا Object كا نسخة جديدة
رقم (2) استدعينا دالة الـ lock وجعلنا تستقل الـ Object وهي بدورها ستقوم بمنع اي Thread اخر الى بعد ان يكتمل عمل نسخة للـ Thread الجديد وعلى حسب الشرط الموجود دالة دالة الـ Lock .
حيث هنا سوف يتم نسخة من الدالة AddOne وبعد الانتهاء من الـ Thread الاول يتم السماح للـ Thread الاخر للقيام بعمله وهنا سوف يفحص هل هناك نسخة موجودة .. وسوف يجدها ويتم التعامل مع النسخة الموجودة باضافة العدد لها
الى هنا انتهت المحاضرة