"سيدي ، خطرت دفاعًا عن التنين". لم يعد يخاف منا! يتم تشغيله من خلال رفرفة أجنحة التنين وتشغيل صفارات الإنذار بصوت عالٍ بحيث يمكن للجميع سماع صوت التنين يقترب.
"هل هذا الدفاع يفعل أي شيء آخر؟"
"لا ، لماذا؟" سيتم تحذيرنا!
"نعم ... تأكل من صفارات الانذار عواء ... وحتى الآن ... تذكرنا عندما نخطط لانقطاع التيار الكهربائي؟ ...
وصف المشكلة
لا تتظاهر هذه الطريقة بمفهوم معالجة الأخطاء في المشروعات المعقدة والمعقدة. بدلاً من ذلك ، إنه مثال على ما يمكن القيام به بأقل الوسائل.
هناك قاعدة جيدة تتمثل في افتراض أنه لا يجب تشغيل أي تأكيد () أثناء تنفيذ البرنامج. وإذا نجح تأكيد واحد على الأقل () عند اختبار التطبيق ، فأنت بحاجة إلى إرسال هذا الخطأ إلى المطور. ولكن ، ماذا لو لم يتم اختبار التطبيق بالكامل؟ وتأكيد () ستعمل للعميل؟ إرسال خطأ إلى المطور؟ إحباط البرنامج؟ في الواقع ، سيكون هذا هو إصدار إصدار التطبيق وسيتم تعطيل التأكيد القياسي () ببساطة. السؤال الذي يطرح نفسه هو التناقض الداخلي للنظام: يجب أن يكون هناك الكثير من التأكيد () لتسهيل اكتشاف الأخطاء ، ولكن يجب أن يكون هناك تأكيد أقل () لمقاطعة المستخدم وعمله مع التطبيق بشكل أقل. لا أرغب بشكل خاص في "السقوط" إذا كان عدد الأشخاص الذين يستخدمون التطبيق يعتمد على استقرار العمل وإذا كان التأكيد () غير مهم بشكل أساسي (يتطلب تصحيحًا ، ولكن يسمح ، على سبيل المثال ، بمواصلة العمل بنجاح كبير).
هذه الاعتبارات تؤدي إلى الحاجة إلى تحسين assert () c / c ++. وحدد وحدات الماكرو الخاصة بك التي تعمل على توسيع وظيفة التأكيد القياسي () - ولكن عن طريق إضافة الحد الأدنى من معالجة الأخطاء. دع وحدات الماكرو هذه تكون.
VERIFY_EXIT (الحالة) ؛
VERIFY_RETURN (الحالة ، ReturnValue) ؛
VERIFY_THROW (شرط ، استثناء) ؛
VERIFY_DO (الحالة) {/ * fail block * /}؛(يمكن تسمية وحدات الماكرو هذه بشكل مختلف. على سبيل المثال ، VERIFY_OR_EXIT () أو VERIFY_OR_RETURN () أو VERIFY_OR_THROW () أو VERIFY_OR_DO (). أو العكس في إصدار أقصر.)
تحتوي وحدات الماكرو هذه ، أولاً ، على تطبيق لكل من إصدار تصحيح الإصدار التجميع وإصدار الإصدار. يتيح لهم ذلك السلوك في إصدار الإصدار من البرنامج. أي أداء الإجراءات ليس فقط أثناء الاختبار ، ولكن أيضا مع المستخدم.
وصف ماكرو
(وصف وحدات الماكرو تقريبي ، والتصميم الآخر ممكن أيضًا.)
1)
VERIFY_EXIT (الحالة) ؛يتحقق من
حالة الشرط وإذا كان غير صحيح ، فإنه يستدعي التأكيد القياسي () (إصدار تصحيح الأخطاء) ، كما أنه يخرج من الوظيفة الحالية (إصدارات تصحيح الأخطاء والإصدار).
2)
VERIFY_RETURN (الحالة ، ReturnValue) ؛يتحقق من
حالة الشرط وإذا كان غير صحيح ، فإنه يستدعي التأكيد القياسي () (إصدار تصحيح الأخطاء) ، كما أنه يخرج من الوظيفة الحالية عن طريق إرجاع
ReturnValue (إصدارات تصحيح الأخطاء وإصداره).
3)
VERIFY_THROW (الحالة ، الاستثناء) ؛يتحقق من
حالة الشرط وإذا كان غير صحيح ، فإنه يستدعي assert () (إصدار التصحيح) القياسي ، ويلقي أيضًا
استثناء (إصدارات debug وإصدار).
4)
VERIFY_DO (الحالة) {/ * fail block * /}؛يتحقق من
حالة الشرط وإذا كان غير صحيح ، فإنه يستدعي assert () (إصدار تصحيح) ، وأيضًا يقوم بتنفيذ
كتلة الفشل أو العملية التي تلي الماكرو مباشرةً (إصدارات تصحيح الأخطاء والإصدار).
من المهم لجميع وحدات الماكرو:
- في جميع الحالات ، يجب أن يكون الشرط صحيحًا "لتمرير" الماكرو وخطأ لتنشيط مسار معالجة الأخطاء الحد الأدنى.
- يقوم كل من وحدات الماكرو بتنفيذ بعض طريقة الحد الأدنى لمعالجة الأخطاء. يعد ذلك ضروريًا لتنفيذ السلوك في حالة وجود أخطاء لم يتم اكتشافها أثناء الاختبار ، ولكن حدثت عند المستخدم. بناءً على التطبيق ، يمكنك إبلاغ المطور بالخطأ الذي حدث عند العميل ، ولكن أيضًا كل تطبيق يوفر طريقة بسيطة للتعافي من الخطأ.
أنماط استخدام ماكرو
بطبيعة الحال ، فإن الشيء الأكثر إثارة للاهتمام هو أن النجوم الخارقة (الأبطال في الحد من الأخطاء في البرامج) هي استخدام هذه وحدات الماكرو.
1) قبل وبعد الشروط.
حالة الاستخدام الأولى هي ظروف ما قبل وبعد. اسمحوا لي أن أذكرك بأن الشروط المسبقة تتحقق من حالة البرنامج (وسيطات الإدخال ، وحالة الكائن ، والمتغيرات المستخدمة) للتأكد من توافقها مع المتطلبات الضرورية لجزء التعليمات البرمجية المنفذة. تهدف شروط النشر (وهي أقل شيوعًا في البرامج) إلى التحقق من أننا حققنا النتيجة المرجوة وأن حالة الكائنات تظل صالحة لجزء الشفرة الحالي.
استخدام وحدات الماكرو المقترحة بسيط - حيث نقوم بتعيين كل تحقق في ماكرو منفصل. نختار وحدات ماكرو بناءً على معالجة الأخطاء التي نحتاج إليها. (VERIFY_EXIT () - معالجة الأخطاء مع الخروج من هذه الوظيفة ، VERIFY_RETURN () - معالجة الأخطاء مع إرجاع قيمة ، VERRIFY_THROW () - معالجة الأخطاء مع استثناء ، إلخ.)
يمكنك أيضًا إضافة أو استخدام ماكرو VERIFY () ، والذي لن يقوم بأي معالجة للأخطاء. قد يكون ذلك مفيدًا ، على سبيل المثال في حالات النشر في نهاية الوظيفة.
تكون وحدات الماكرو هذه مكتفية ذاتيًا تمامًا إذا كنت تستخدم مبادئ الشفرة الخالصة وتخصيص وظائف كافية لتنفيذ الإجراءات الذرية. يمكن لكل وظيفة التحقق من حالة الكائن ، وسيطات الإدخال ، إلخ. لتنفيذ عملها الذري.
2) دلالات المعاملة.
أيضًا ، يمكن استخدام وحدات الماكرو هذه لتطبيق التعليمات البرمجية مع دلالات المعاملة. يتم فهم هذه الدلالات على النحو التالي: 1) الإعداد التدريجي لعملية مع التحقق من نتائج كل مرحلة من مراحل الإعداد ؛ 2) تنفيذ الإجراء فقط في حالة نجاح جميع مراحل الإعداد ؛ 3) رفض الوفاء ، إذا لم يتم استيفاء بعض الشروط في مرحلة الإعداد (مع التراجع ممكن من الوفاء).
3) تصميم الكود ، مع مراعاة التمديد المحتمل.
ينطبق هذا بشكل خاص على المكتبات والرمز العام ، والذي يمكن تطويره مبدئيًا في نفس سياق شروط التنفيذ ، ويمكن البدء لاحقًا في استخدامه مع شروط أخرى (البدء في الاستخدام بشكل مختلف). في هذه الحالة ، يمكن لوحدات الماكرو هذه وصف "حدود" وظيفة الكود. حدد ما كان ينظر إليه في البداية كخطأ وما كان ناجحًا. (هذا النهج قريب من شروط ما قبل النشر الكلاسيكية). بالطبع ، أكتب "الحدود" بين علامات اقتباس ، لأن يمكن مراجعة هذه الحدود ، ولكن من المهم تحديد (أو بالأحرى نقل مطوري المستقبل) معرفة الحدود المقبولة لتصميم الكود.
تنفيذ الماكرو
أفترض أن معظم مطوري المستوى المتوسط لن يواجهوا مشكلات في تطبيق وحدات الماكرو هذه. ولكن إذا كنت بحاجة إلى معلومات ، فسأكرس بعض النقاط المهمة.
يجب أن تكون وحدات الماكرو قابلة للتمثيل كبيان واحد. ما الذي يمكن فعله بالقيام {} بينما البنيات (الخاطئة) أو ما شابه ذلك. على سبيل المثال ، مثل هذا:
#define VERFY_EXIT(cond) \ do{bool _= (bool)(cond); assert(_); if(!_) {return;}} while(false) \
ثم يمكنك كتابة الكود التالي:
if(a > 0) VERIFY_EXIT(a%2==0);
بالطبع ، هذه ليست سوى واحدة من إمكانيات التنفيذ. يمكنك تطبيق وحدات الماكرو بطرق أخرى.
سكرتير خاص معركة ناجحة مع الكون ، سوبرمان!