فحص خصائص الشرطية المعقدة
لا يشرع المطورون في كتابة مجموعة معقدة من if العبارات من البداية. بدلا من ذلك ، تتراكم الشرطيات المعقدة تدريجيا مع تطور قاعدة التعليمات البرمجية. يمكن أن يساعدك فهم هذه العملية التطورية في تحديد هذه الأنماط في مشاريعك الخاصة (ومن الناحية المثالية منعها مبكرا).
كيف تظهر الشرطيات المعقدة
غالبا ما تنشأ الشروط المعقدة من مجموعة من العوامل:
إضافات الميزات الإضافية: غالبا ما يبدأ الكود بهيكل قرار مباشر لسيناريو بسيط. بمرور الوقت ، تتم إضافة ميزات أو متطلبات جديدة. في كل مرة ، بدلا من إعادة تصميم المنطق ، قد يختار المطور المسار الأقل مقاومة: ما عليك سوى إضافة آخر
ifأو توسيع الشرط الموجود. على سبيل المثال، قد يبدأ روتين معالجة الأوامر بالتحققif (order.Total > 100) { applyDiscount(); }من . في وقت لاحق ، يتم إضافة خصم خاص لعملاء VIP كشرط آخر ، ثم تتم إضافة عرض ترويجي للعطلات كشرط متداخل داخل خصم VIP ، وما إلى ذلك. يبدو كل تغيير فردي صغيرا ، لكنه يتراكم في شبكة معقدة من الشروط.إصلاحات أخطاء حالة الحافة: مصدر شائع آخر هو التصحيحات السريعة للأخطاء. لنفترض أن مراجعة ضمان الجودة تنشئ تذكرة تصف المشكلة التالية: "إذا تم قفل حساب المستخدم وحاول إعادة تعيين كلمة المرور، فإن النظام يتصرف بشكل غير صحيح". قد يعالج المطور هذه المشكلة عن طريق إدراج فحص شرطي مستهدف في التعليمات البرمجية. على سبيل المثال ، التعليمات البرمجية التي تنفذ المنطق التالي: "إذا كان accountLocked و passwordReset ، فقم بعمل X". يعمل هذا الإصلاح ويجتاز الرمز الاختبارات المرتبطة. ومع ذلك ، فإنه يضيف فرعا آخر إلى المنطق. على مدار عمر المشروع ، قد يتم تكديس العديد من إصلاحات حالة الحافة هذه ، كل منها يضيف المزيد من التداخل أو التعقيد. ما بدأ كبسيط
if/elseيمكن أن يتحول إلى شجرة متعددة الفروع حيث يتم تثبيت الحالات الخاصة دون إعادة هيكلة.المتطلبات المتطورة: غالبا ما تنمو المتطلبات إلى ما هو أبعد من التصميم الأصلي للكود. ضع في اعتبارك نظام الموافقة على القروض الذي يتخذ قرارا أوليا عن طريق التحقق من بعض المقاييس الأساسية (درجة الائتمان والدخل). مع توسع الأعمال ، فإنهم يقدمون المزيد من القواعد: التعامل الخاص مع المقترضين لأول مرة ، والموافقة المشروطة مع الضمانات ، والقواعد المختلفة لأنواع القروض المختلفة ، والشيكات التنظيمية ، وما إلى ذلك. إذا لم تتم إعادة هيكلة الكود الأصلي ، فإن الميل الطبيعي هو تداخل المزيد
ifمن العبارات. على سبيل المثال ، داخلif (creditOK)الكتلة ، أضفif (hasCollateral) ... else ...، وداخل تلك الكتلة ، ربما آخرifللعلم التنظيمي. تزيد كل قاعدة جديدة من التداخل أو تضيف فروعا جديدة على نفس المستوى. على مدى أشهر أو سنوات ، تتحول وظيفة الموافقة على القرض إلى طريقة عملاقة يبلغ طولها مئات الأسطر ، مع مجموعة متشابكة من الظروف تغطي كل سيناريو تواجهه الشركة.عدم وجود إعادة بناء دوري للتعليمات البرمجية: تتطور مشكلات تعقيد التعليمات البرمجية عندما تحدث إضافات متزايدة دون مراجعات تنظف بنية التعليمات البرمجية. من الشائع في التطوير سريع الخطى إلغاء أولوية إعادة البناء ("إنه يعمل ، دعونا لا نلمسه"). نتيجة لذلك ، يظل المنطق الشرطي الذي يجب إعادة تصميمه (تقسيمه إلى وظائف أصغر ، أو تحويله إلى جدول تكوين ، وما إلى ذلك) في شكل غير مرغوب فيه بشكل متزايد. بحلول الوقت الذي يلاحظ فيه شخص ما مدى صعوبة الكود ، تكون الوظيفة هشة للغاية لدرجة أن الناس يترددون في إعادة هيكلتها - وهو تراكم كلاسيكي للديون التقنية.
علامات الشروط المعقدة للغاية
بصفتك مطورا ، يجب أن تكون على اطلاع على العلامات الحمراء في التعليمات البرمجية التي تشير إلى أن التعقيد الشرطي خارج عن السيطرة:
مستويات التداخل العميق: تعد الوظائف التي تحتوي على أكثر من 2-3 مستويات من العبارات المتداخلة
if(خاصة مع الكتل المتداخلةelse) مرشحة قوية. بصريا ، يشكل الرمز شكل سهم بمسافة بادئة إلى اليمين ، مما يجعل من الصعب محاذاة المنطق في عقلك. إذا وجدت نفسك تحسب الأقواس أو المسافات البادئة لمعرفة الأزواجelseالتي ،ifفهذه علامة سيئة.سلاسل طويلة من حالات else-if أو التبديل: سلسلة من
else if (...) { ... } else if (...) { ... } ...ذلك تستمر لعشرات الأسطر يمكن أن تشير إلى أن الكود يتعامل مع العديد من المتغيرات في مكان واحد. في بعض الأحيان يمكن أن يكون البيان الطويلswitchمع العديد من الحالات متكافئا. غالبا ما يمكن تبسيط هذه الهياكل أو تقسيمها إلى أجزاء أصغر (أو تعيينات تعتمد على البيانات) إذا كانت تمثل العديد من الظروف الثابتة.التعبيرات المنطقية المعقدة: الشرطيات التي تجمع بين العديد من المصطلحات ، على سبيل المثال:
if ((A && B && !C) || (D && (E || !F))) { ... }يصعب قراءة مثل هذه التعبيرات ويصعب فهمها بشكل صحيح. إذا رأيت منطقا شرطيا مع عوامل تشغيل متعددة&&||ممزوجة بالنفي!، فقد يستفيد من التبسيط (على سبيل المثال ، عن طريق التقسيم إلى شروط فرعية أكثر وضوحا أو استخدام المتغيرات التوضيحية).التعبيرات المنطقية المعقدة: الشرطيات التي تجمع بين العديد من المصطلحات ، على سبيل المثال:
if ((A && B && !C) || (D && (E || !F))) { ... }يصعب قراءة مثل هذه التعبيرات ويصعب فهمها بشكل صحيح. إذا رأيت منطقا شرطيا مع عوامل تشغيل متعددة&&||ممزوجة بالنفي!، فقد يستفيد من التبسيط (على سبيل المثال ، عن طريق التقسيم إلى شروط فرعية أكثر وضوحا أو استخدام المتغيرات التوضيحية).عمليات التحقق المتكررة وتكرار التعليمات البرمجية: ابحث عن الحالات التي يظهر فيها نفس الشرط أو التعليمات البرمجية المشابهة في فروع متعددة. على سبيل المثال ، إذا رأيت
if (user.IsAdmin)جزأين مختلفين منif/elseالسلم ، فقد تتمكن من تقييم الحالة في موقع واحد إذا قمت بإعادة هيكلة المنطق. قد تجد أيضا فرعين من شرطي يحتويان على منطق تعليمات برمجية مماثل مع اختلافات طفيفة. إذا لاحظت هذا النمط ، فيمكن إعادة بناء الشرطية لتجنب الازدواجية.استخدام متغيرات "العلامة" للتحكم في التدفق: في بعض الأحيان يقدم المطورون علامات مؤقتة كحل بديل للمنطق المعقد (على سبيل المثال،
bool isValid = false; ... if (condition) { isValid = true; } ... if (isValid) { ... }). على الرغم من أن استخدام العلامات ليس هو نفسه شرطيات التداخل ، إلا أنه غالبا ما يكون استجابة للتعقيد - لا يمكن للرمز القيام بسهولة بما يحتاجه في تمريرة واحدة ، لذلك يقوم بتعيين علامة ليتم التحقق منها لاحقا. قد تتمكن من التخلص من هذا النمط عن طريق إعادة هيكلة الشروط أو استخدام العوائد المبكرة.
ملخص
غالبا ما تنشأ الشروط المعقدة من التغييرات المتزايدة وإصلاحات الأخطاء والمتطلبات المتطورة دون إعادة بناء التعليمات البرمجية المصاحبة. تشمل علامات الشرطيات المعقدة للغاية التعشيش العميق ، وسلاسل طويلة من الظروف ، والتعبيرات المنطقية المعقدة ، والفحوصات المتكررة ، واستخدام متغيرات العلم. يعد التعرف على هذه الأنماط الخطوة الأولى نحو تحسين جودة التعليمات البرمجية من خلال إعادة الهيكلة.