تأجيل إعطاء القيم الابتدائية للكائنات (تأجيل التهيئة) Lazy initialization
هناك سببان ريئيسيان لتأجيل تهيئة initialization لكائن Object ما وهما كالتالي
1- أن يكون الكائن ذو ثقل في الذاكرة
2- أن يكون الكائن مكلف في عملية الإنشاء مع أنه اختياري الاستخدام بمعنى أنه يستخدم في بعض الأحيان وليس في جميعها
بالنسبة للسبب الأول نجد أن عملية تأجيل التهيئة مفيدة في الغالب
أما بالنسبة للسبب التالي فليس بالضرورة أن يكون تأجيل التهيئة للكائن ذو فائدة قد يكون في بعض الأحيان ذو ضرر
مثال:
في برامج الواقعية real-program نحن نحتاج للوقت بشكل كبير خصوصا في حالة تعدد الخيوط multithreadهىل
لذا نعمد في بعض الأحيان إلى إنشاء الكائنات بشكل متلهف عندما يكون المعالج خالي
وفي أحيان أخرى نعمل على تأجيل التهيئة إذا كان المعالج مشغول في برامج ذات أهمية priorty أعلى
لذا نعمد إلى تأجيل تهيئة الكائنات للبرامج الأقل أهمية
بعد أن تعرفنا على ماهية تأجيل التهيئة يأتي السؤال المهم كيف أقوم بتأجيل تهيئة كائن ما
المثال التالي مع الشرح التابع له يسوضح العملية بإذن الله
public final class MyFrame extends Frame{ private MessageBox mb_ ; //null, implicit private void showMessage(String message) { if(mb_==null)//تنفذ عند أول نداء لهذه الطريقة بعد ذلك تهمش بشكل دائم mb_=new MessageBox(); //set the message text mb_.setMessage( message ); mb_.pack(); mb_.show(); } }
المثال يتحدث عن نافذة Frame تقوم بإطلاع المستخدم لها على بعض الأخطاء من خلال الكائن mb_
نلاحظ التالي ليس بالضرورة أن تحصل أخطاء عندي في النافذة
بالتالي ليس بالضرورة أني سأحتاج الكائن mb_
فلماذا يجب عليه أن أبنيه مبكراً لما لا أتأخر قليلاً حتى يحصل الخطأ الأول
بالتالي عندما يحصل الخطأ الأول فعليه أن أن أفحص إذا كان الكائن يحتوي قيمة أم أنه فارغ null
إن كان فارغ فأنا بحاجة إلى بنائه وإلا فأنا سأكمل بدون مشاكل
محظورات عليك التنبه لها
1- لا تقوم بإعطاء القيمة null للكائن مرة أخرى لأنك تتحمل التعقيد لإنشاء الكائن مرة أخرى
(قد تحتاج إلى ذلك في بعض الحالات كأن يكون عندك طريقة تعدل خصائص النافذة وأنتا لا تريد أن
يسري التعديل على جميع النوافذ التي تظهر بعد ذلك)
2- المثال السابق لا يمكنك استخدامه في حالة تعدد الخيوط لأنك قد تقوم ببناء الكائن عدة مرات لا مرة واحدة
وذلك قد يحملك كلغة عالية
الحل لهذه المشكلة هي أن تستخدم كلمة synchronized مع الطريقة السابقة
لكن ماذا عن التكلغة الخاصة بهذه الكلمة في ما بعد فهي قد تعطل عملك في ما يلي
لهذا نستخدم تقنية الفحص الثنائي double-check idiom
ذلك أنك تقوم بالفحص بداية ثم تقوم بعملية التزامن synchronization
التي تحتوي على نفس الفحص السابق
المثال التالي يوضح المطلوب
public final class MyFrame extends Frame{ private MessageBox mb_ ; //null, implicit private void showMessage(String message) { if(mb_==null){//تنفذ عند أول نداء لهذه الطريقة بعد ذلك تهمش بشكل دائم synchronized(MyFrame.class) { //هنا نفحص مرة أخرى لكي نضمن أنه لا يوجد خيط آخر سيقوم ببناء الكائن مرة أخرى if(mb_==null) mb_=new MessageBox();//safe } } //set the message text mb_.setMessage( message ); mb_.pack(); mb_.show(); } }
نلاحظ أن الفحص الأول يمنع التكلفة الخاصة بالتزامن
والفحص الثاني يمنع التكلفة الخاصة بإعادة بناء الكائن من أي خيط نفذ من الفحص الأول
المراجع حسب الأهمية:
مقال بعنوان Java Tip 67: Lazy instantiation من موقع عالم الجافا
http://www.javaworld.com/javaworld/javatips/jw-javatip67.html
مقال بعنوان Lazy initialization
http://www.javapractices.com/Topic34.cjp
في النهاية أحب أن أنوه على أن هذا المقال لم يترجم حرفياً من المراجع السابقة
وإنما كان نتاج إطلاع على الموضوع من عدة مقالات عربية وأجنبية في النهاية وجدت أنني
أستسقي غالب أفكاري من هذه المقالات فلم أحب أن أنسب لنفسي ما لم تقم به
المترجم:علاء الصالحي
البريد:alaadiaa1@hotmail.com
سبحانك اللهم وبحمدك واستغفرك اللهم وأتوب إليك
بصراحة انا لا أفهم كثيرا في البرمجة ولكن حبيت المرور عليك واسلم عليك
شكراً لك أخي أبو مروان
مرورك دائماً يسعدني
الله معك
مقال ممتاز ولي سؤال
ما وظيفة هذه الجملة
synchronized(MyFrame.class)
يعني ما معني .class في الجملة وظيفتها ايه معلش ممكن يكون سؤال غبي شوية
في جافا هناك ما يسمى بالإنعكاس reflection
بإمكانك البحث عن الموضوع بشكل أكبر
أعتذر على التأخير في الرد
بسبب ظروف الهجمة الصهيونية على غزة
تحياتي
[…] المتغير ani هو كائن من فئة المحرك وأسلوب الفحص هذا يسمى تأجيل إعطاء القيم الابتدائية للكائنات lazy intialization معنى أن يكون ani بـ null هو أن المحرك يعمل لأول مرة ومعنى […]