كتلة معالجة الاستثناءات لـ Microsoft - أليس هذا مثالًا مثاليًا للهندسة الزائدة؟

StackOverflow https://stackoverflow.com/questions/408480

سؤال

منذ أن طرحت Microsoft كتل التطبيقات، التقيت بأشخاص يستخدمون كتلة تطبيق معالجة الاستثناء.لقد ألقيت مؤخرًا نظرة فاحصة بنفسي وسألخص الوظيفة الأساسية على النحو التالي (تخطي الكتلة التالية إذا كنت تعرف بالفعل ما تفعله):

تهدف كتلة تطبيق معالجة الاستثناءات إلى المركزية وجعلها قابلة للتكوين بالكامل باستخدام ملفات التكوين التالية مهام معالجة الاستثناءات الرئيسية:

  • تسجيل استثناء
  • استبدال استثناء
  • التفاف استثناء
  • نشر الاستثناء
  • إلخ.

تقوم المكتبة بذلك عن طريق تعديل كتل المحاولة الخاصة بك على النحو التالي:

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

بناءً على ما تم تحديده في app.config لاسم السياسة (انظر هنا للحصول على المستندات) ، HandleException إما ...

  • طرح استثناء جديد تمامًا (استبدال الاستثناء الأصلي)
  • قم بلف الاستثناء الأصلي في استثناء جديد ثم قم برميه
  • ابتلاع الاستثناء (أي.لا تفعل شيئا)
  • هل قمت بإعادة طرح الاستثناء الأصلي

بالإضافة إلى ذلك، يمكنك أيضًا تهيئته للقيام بالمزيد من الأشياء مسبقًا (على سبيل المثال.سجل الاستثناء).

الآن ها هي مشكلتي:أفشل تمامًا في رؤية كيف يمكن أن يكون من المفيد جعله قابلاً للتكوين سواء تم استبدال الاستثناء أو تغليفه أو ابتلاعه أو إعادة طرحه.في تجربتي، يجب اتخاذ هذا القرار في الوقت الذي تكتب فيه الكود لأنه سيتعين عليك عادةً تغيير الكود المحيط أو رمز الاتصال عند تغيير سلوك معالجة الاستثناء.

على سبيل المثال، من المحتمل أن تبدأ التعليمات البرمجية الخاصة بك في التصرف بشكل غير صحيح عندما تقوم بإعادة التكوين بحيث يتم الآن ابتلاع استثناء معين تم طرحه عند نقطة معينة بدلاً من إعادة طرحه (قد يكون هناك تعليمة برمجية بعد كتلة الالتقاط التي يجب عدم تنفيذها عند حدوث الاستثناء).الأمر نفسه ينطبق على جميع التغييرات الأخرى المحتملة في معالجة الاستثناءات (على سبيل المثال.استبدال -> إعادة الرمي، ابتلاع -> لف).

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

هل كانت مفيدة؟

المحلول

إذا كنت تستخدم استثناءات للتحكم في التدفق، فقد ترغب في الابتعاد عن معالجة الاستثناءات المستندة إلى السياسة.

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

على سبيل المثال، إذا كنت تقوم بتطوير واجهة برمجة التطبيقات (API)، فقد ترغب في أن تقوم كل وظيفة في واجهة برمجة التطبيقات (API) الخاصة بك بطرح الاستثناءات القياسية فقط (ArgumentException, ، وما إلى ذلك)، بالإضافة إلى الاستثناء الخاص بالمكتبة الخاصة بك في حالة وجود استثناء داخلي غير قياسي (على سبيل المثال.أ MyLibraryException).في هذا النوع من الحالات، كل ما يهم هو أن شيئًا ما لم يعمل بشكل صحيح.أنت لا تقوم بتفكيك الاستثناء ومعرفة الخطأ الذي حدث.أنت ببساطة تعترف بحقيقة ذلك بعضحدث خطأ ما، والذي من المفترض أن تفعله بعضالشيء الآن.

الذي - التي بعضيجب أن يكون الشيء قابلاً للتكوين، لأنه لا يهم حقًا ما تفعله.عرض صندوق الرسائل للمستخدم؟مشروط أو غير مشروط؟تسجيل الاستثناء؟كيف تريد تسجيل الاستثناء؟استدعاء خدمة ويب التسجيل؟إلحاق بملف السجل؟هل تريد الكتابة إلى سجل أحداث Windows؟أدخل إدخال في قاعدة البيانات؟إدراج إدخال في قاعدتي بيانات؟لا يهم حقًا بقية طلبك.يكون اختيار كيفية التعامل مع الاستثناء متعامدًا تمامًا مع بقية التطبيق.

(جانبًا، هذه ليست الطريقة التي سأتعامل بها مع معالجة الاستثناءات القائمة على السياسات القابلة للتكوين.سأميل أكثر نحو أسلوب AOP، مثل تسجيل معترض مسجل الاستثناءات في الحاوية.)

نصائح أخرى

أواجه هذه المشكلة عندما أقوم بتطوير وظائف ليس لها حالة قابلة للاسترداد.أعتقد أن معالجة الاستثناءات المدفوعة بالسياسة مفيدة بالفعل وتضمن أن جميع المطورين الآخرين الذين يشكلون جزءًا من هذا المشروع يلتزمون فعليًا بمعيار الاستثناءات غير القابلة للاسترداد.

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

يجب أن أتفق مع العبارة القائلة بأن "كتلة معالجة الاستثناء تحل المشكلات التي لا توجد بالفعل في الممارسة العملية". لقد استخدمت الكتلة منذ إصدارها ونادرا ما أشعر أنني أكسب الكثير من خلال استخدامها.حسنا، ربما قليلا من الصداع.:)

قبل أن أبدأ، سأعترف بأنني أحب حماية الاستثناءات عند حدود خدمة WCF وظائف.ومع ذلك، فقد تمت إضافته مؤخرًا إلى حد ما، ولا يتضمن أي تعليمات برمجية - فقط السمات والتكوين، وليست الطريقة التي يتم بها بيع الكتلة عادةً.هذه هي الطريقة التي تعرضها Microsoft في http://msdn.microsoft.com/en-us/library/cc309250.aspx

alt text

في نظري ما ورد أعلاه هو التحكم في التدفق.

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

عندما تقوم بدمج جانب التحكم في التدفق مع الكود أعلاه، فأنت بالتأكيد لست كذلك جعل الكود الخاطئ يبدو خاطئًا.(ناهيك عن أن بنية if (rethrow) لا تقدم قدرًا كبيرًا من التجريد.) وهذا يمكن أن يجعل الصيانة أكثر صعوبة بالنسبة للمطورين غير المطلعين على تعريفات السياسة.إذا postHandlingAction في ملف التكوين الذي تم تغييره (من المحتمل أن يحدث ذلك في مرحلة ما) من المحتمل أن تجد التطبيق يتصرف بطرق غير متوقعة لم يتم اختبارها من قبل.

ربما لن أجد الأمر مرفوضًا إذا لم تتعامل الكتلة مع التحكم في التدفق ولكنها سمحت لك ببساطة بربط المعالجات معًا.

ولكن ربما لا.لا أذكر في الواقع أنه طُلب مني يومًا ما:

  • إضافة جزء جديد من الوظائف عند التعامل مع استثناء (على سبيل المثال.بالإضافة إلى تسجيل الدخول إلى سجل الأحداث أيضا إرسال بريد إلكتروني.في الواقع، يمكن لكتلة التسجيل القيام بذلك من تلقاء نفسها إذا كنت قد قمت بالفعل بتسجيل الاستثناء بنفسك.:))
  • تغيير سلوك معالجة الاستثناء (ابتلاع أو إعادة طرح أو طرح جديد) عبر "السياسة" بأكملها.

أنا لا أقول أن هذا لا يحدث (أنا متأكد من أن هناك من لديه قصة!) ؛أشعر فقط أن كتلة تطبيق معالجة الاستثناءات تجعل البرامج أكثر صعوبة في الفهم والصيانة وهذا عادة ما يفوق الوظيفة التي توفرها الكتلة.

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

الآن مع هذه السياسة، يمكننا بدء التسجيل في أي وقت دون الحاجة إلى إعادة التشغيل أو رش منطق التسجيل دون داع في جميع أنحاء التطبيق.يمكننا الآن مشاهدة الاستثناءات وما شابه ذلك دون الحاجة إلى إيقاف تشغيل التطبيق.

البرمجة الذكية إذا سألتني ...

بكل بساطة:إذا كنت تريد معالجة استثناءات مختلفة في كود الإصدار الخاص بك عن تلك الموجودة في كود التصحيح الخاص بك، فسيكون ذلك مفيدًا.

في رأيي، إحدى القيم الحقيقية لاستخدام كتلة معالجة الاستثناءات تبدأ بسطر واحد من التعليمات البرمجية في كتلة الالتقاط الخاصة بك:

bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");

سطر واحد من التعليمات البرمجية - ما مدى سهولة الحصول عليه؟خلف سطر واحد من التعليمات البرمجية، تجعل السياسة، كما تم تكوينها، التعيين/التحديثات على السياسة يتم تنفيذها بسهولة، كل ذلك دون الحاجة إلى إعادة ترجمة التعليمات البرمجية المصدر.

كما ذكرنا سابقًا، يمكن لسياسة الاستثناء تنفيذ العديد من الإجراءات - أيًا كان ما تم تعريفه في سياستك.إخفاء التعقيد خلف سطر واحد من التعليمات البرمجية كما هو موضح داخل كتلة الالتقاط، هو المكان الذي أرى فيه قيمة حقيقية.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top