مراجعات الكود: المصادر الشائعة للانتهاكات الشديدة وكيفية تجنب الحجج المتعلقة بإصلاحها

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

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

المشغل الشرطي مقابل البيان

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

إذا كانت العبارة: يمكن أن تسهم العبارة if في التعليمة البرمجية الضخمة الفظيعة ، عندما تكون كثافة الشروط عالية. الكثافة العالية تجعل الكتلة أو الطريقة تبدو منتفخة. ومع ذلك ، فإن التعليمات البرمجية المكتوبة بـ if-statement يمكن تصحيحها أيضًا ، حيث يمكن للمطور التنقل عبر كل سطر.

إذا (label1IsRequired) {
 label1.Color = "red"؛
} آخر {
 label1.Color = "black"؛
}
إذا (label2IsRequired) {
 label2.Color = "red" ؛
} آخر {
 label2.Color = "black" ؛
}
إذا (label3IsRequired) {
 label3.Color = "red" ؛
} آخر {
 label3.Color = "black" ؛
}

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

healthIndicatorColor = (الصحة == "جيد")؟ "الأخضر": (الصحة == "عادل")؟ "الأصفر": (الصحة == "الفقراء")؟ "أحمر": (الصحة == "life_support")؟ "البرتقالي": "الأرجواني" ؛

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

إذا (الصحة == "جيد") {
 healthIndicatorColor = "أخضر" ؛
} آخر إذا (الصحة == "عادل") {
 healthIndicatorColor = "أصفر" ؛
} آخر إذا (الصحة == "الفقراء") {
 healthIndicatorColor = "red" ؛
} آخر إذا (الصحة == "life_support") {
 healthIndicatorColor = "برتقالي" ؛
} آخر {
 healthIndicatorColor = "أرجواني" ؛
}
label1.Color = (label1IsRequired)؟ "أحمر": "أسود" ؛
label2.Color = (label2IsRequired)؟ "أحمر": "أسود" ؛
label3.Color = (label3IsRequired)؟ "أحمر": "أسود" ؛

بيانات إرجاع متعددة مقابل بيان إرجاع واحد

نمطان خاصان يؤديان إلى الوسائط هما المرتجعات المتعددة والإرجاع الفردية. تظهر خلافات حول ما إذا كان يجب أن تحتوي الطرق على عبارة إرجاع واحدة أو ما إذا كانت عبارات الإرجاع المتعددة مقبولة. كل نهج له ايجابيات وسلبيات.

عبارات إرجاع متعددة: يمكن أن تسهم عبارات إرجاع متعددة في تعليمة برمجية يصعب فهمها ومتابعتها واختبارها. ومع ذلك ، يمكن أن تكون الطرق ذات العوائد المتعددة أقصر من الدوال ذات العائد الفردي.

SomeDataType someMethod (param1، param2، param3) {
 SomeDataType retVal؛
 إذا (param1 == فارغة) {
 retVal = فارغة
 }
 if (retVal == null) {
 عودة retVal.
 }
 
 إذا (param2! = خالية)
 retVal = param2 ؛
 }
 إذا (retVal.Equals (PARAM2)) {
 عودة retVal.
 }
 
 retVal = param3؛
 عودة retVal.
}

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

SomeDataType someMethod () {
 SomeDataType retVal؛
 // مئات أو الآلاف من خطوط الأسطر
 عودة retVal.
}

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

SomeDataType someMethod (param1، param2، param3) {
 if (param1 == null || param3 == null) {
 عودة لاغية
 }
 
 SomeDataType retVal = null؛
 إذا (param2! = فارغة)
 retVal = param2 ؛
 } آخر إذا (param1! = خالية)
 retVal = param1؛
 } ele if (param3! = null) {
 retVal = param3؛
 }
 عودة retVal.
}
SomeDataType someMethod (param1، param2) {
 SomeDataType retVal = null؛
 من أجل (int i = 0 ؛ i  إذا (PARAM1 [أنا] .equals (PARAM2)) {
 retVal = param1 [i]؛
 استراحة؛
 }
 }
 عودة retVal.
فاصل ومتابعة الاستخدام في الحلقات

الاختراق والاستمرار في البناء هي موضوع نقاشات حادة. على جانب واحد من الوسيطة ، يجادل المطورين أن الاختراق والمتابعة يمكن أن يسهل تدفق التحكم. يؤكد مبرمجون آخرون أن هذه الميزات تعقد منطق البرنامج. يمكن بالتأكيد استخدام Break and Continue لتبسيط التعليمات البرمجية أو تعقيدها. هذه الخطوط يمكن رصدها.

فاصل ومتابعة الاستخدام: يمكن للعناصر تبسيط التعليمات البرمجية ، لكن يمكنها أيضًا تعقيدها دون داع.

SomeDataType someMethod (param1، param2) {
 SomeDataType retVal = null؛
 من أجل (int i = 0 ؛ i  إذا (param1 [i] == فارغة) {
 استمر؛
 }
 إذا (PARAM1 [أنا] .equals (PARAM2)) {
 retVal = param1 [i]؛
 استراحة؛
 }
 }
 عودة retVal.
}
SomeDataType someMethod (data، param1) {
 SomeDataType retVal = null؛
 قم بعمل ما:
 لـ (int i = 0 ؛ i  إذا (i> = data.length) {
 استراحة؛
 }
 إذا (بيانات [أنا] .equals (PARAM1)) {
 retVal = البيانات [i] ؛
 } آخر {
 استمر؛
 }
 }
if (retVal == null) {
 البيانات - refreshData () ؛
 غوتو dosomething.
 }
عودة retVal.
}

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

SomeDataType someMethod (data، param1) {
 SomeDataType retVal = null؛
 من أجل (int i = 0 ؛ i  إذا (البيانات [i] == فارغة) {
 استمر؛ / / تخطي بقية الحلقة
 }
 إذا (بيانات [أنا] .equals (PARAM2)) {
 retVal = البيانات [i] ؛
 استراحة؛ / / لا تقم بإجراء المزيد من عمليات b / c
 }
 }
 عودة retVal.
}

استثناءات دفاعية

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

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

باطل someMethod (param1 ، param2) {
 if (param1 == null || param2 == null) {
 رمي ArgumentNullException جديد ("معلمة واحدة أو أكثر مفقودة") ؛
 }
 / / تفعل الاشياء الطريقة
}
باطل someMethod (param1 ، param2) {
 // عشرات خطوط الشيكات الدفاعية .....
 / / تفعل بقية الطريقة
}

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

باطل بعض someMethod (param1 ، param2) {
 / / تحقق من كل معلمة بطريقة عامة
 if (param1 == null || param2 == null) {
 رمي ArgumentNullException جديد ("معلمة واحدة أو أكثر مفقودة") ؛
 }
 
 / / تجنب المشاكل التي تسببها البيانات غير الصحيحة
 إذا (! isValid (param1) ||! isValid (param2)) {
 رمي InvalidParameterException الجديد ("معلمة واحدة أو أكثر غير صالحة") ؛
 }
 
 / / تفعل شيئا مع المعلمات
}

يتم إحتوائه

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