4.1 مقاييس تعقيد الكود
نظرة عامة والدوافع
التعقيد الدوري، الذي قدّمه Thomas J. McCabe عام 1976، يعدّ عدد المسارات المستقلة عبر تدفق تحكم قطعة من الكود: كل if، وحلقة، وفرع يُضيف إلى العدد. لا يزال المقياس الأكثر استخدامًا لتعقيد الكود بعد قرابة خمسين عامًا، إلى جانب أقارب مثل التعقيد المعرفي (الذي يُرجِّح تدفق التحكم المتداخل والصعب المتابعة أكثر من عدّ McCabe الخطي الأصلي) وعمق التداخل. تشترك هذه المقاييس في رؤية حقيقية ومُثبَتة الصلاحية: الكود بمسارات مستقلة أكثر عبره أصعب اختبارًا بالكامل، وأصعب استيعابًا، وفي عقود من البحث التجريبي، أكثر احتمالًا بشكل قابل للقياس لاحتواء عيوب.
يعامل هذا الموضوع تلك الرؤية باحترام حقيقي بينما يعامل حدودها بنفس الجدية. تقيس مقاييس التعقيد خاصية محددة واحدة للكود، ويمكن لقاعدة كود أن تكون بسيطة وفق كل مقياس تعقيد بينما تبقى مُصمَّمة بشكل سيء، أو مُسمّاة بشكل سيء، أو غير متماسكة مفاهيميًا بطرق لا تستطيع أي خوارزمية عدّ فروع اكتشافها. بالمقابل، بعض المشكلات المعقدة بشكل لا يمكن اختزاله تتطلب حقًا كودًا معقدًا لحلها بشكل صحيح، وفريق مضغوط لتقليل درجة تعقيد يمكن أن يُنتج كودًا يُسجِّل جيدًا بينما يصبح فعليًا أصعب فهمًا، ناشرًا التعقيد الأساسي عبر ملفات وطبقات تسلسل أكثر بدلًا من تقليله.
بالنسبة للفرق الكبيرة، تكتسب مقاييس التعقيد قيمتها كأداة فرز: طريقة لإيجاد، بين آلاف الملفات، المجموعة الفرعية الصغيرة الأكثر احتمالًا لمكافأة نظرة أقرب، لا كحكم مستقل على جودة الكود. المؤسسات الكبرى والمنظمات الحكومية التي تصون قواعد كود أكبر من أن يقرأها أي فرد بالكامل تعتمد على وظيفة الفرز هذه لتوجيه جهد إعادة الهيكلة والمراجعة النادر حيث سيفعل أكبر خير.
المبادئ الأساسية
- تتنبأ مقاييس التعقيد بصعوبة الاختبار والعيوب؛ لا تقيس الجودة مباشرة. عاملها كمدخل واحد، لا حكمًا.
- درجة التعقيد عرضة للتلاعب عبر التعتيم، لا التبسيط الحقيقي فقط. تقسيم التعقيد عبر ملفات أكثر يمكن أن يُخفِّض الدرجة بدون جعل الكود أسهل فهمًا فعليًا.
- بعض التعقيد أساسي، لا عرضي. مشكلة صعبة حقًا قد تتطلب كودًا معقدًا حقًا؛ الهدف تقليل التعقيد العرضي، لا القضاء على كل تعقيد بلا تمييز.
- استخدم مقاييس التعقيد للفرز، لا كبطاقة تسجيل فردية أو للفريق. تشير إلى أين تنظر، لا من تلوم.
- الاتجاه والقيم الشاذة تهم أكثر من أي عتبة مطلقة. اتجاه متصاعد أو قيمة شاذة متطرفة أكثر قابلية للتصرف من متوسط ثابت على مستوى قاعدة الكود بأكملها.
التوصيات
استخدم مقاييس التعقيد لفرز جهد المراجعة وإعادة الهيكلة
شغّل تحليل التعقيد عبر قاعدة الكود واستخدم النتائج لتحديد أولويات أين ستُثمِر مراجعة بشرية أقرب أو استثمار إعادة هيكلة أكثر: الدوال أو الملفات المُسجِّلة أعلى بكثير من النطاق النموذجي لقاعدة الكود نفسها هي أعلى الأماكن قيمة للنظر أولًا. هذا الاستخدام الفرزي، إيجاد أين تنظر، هو التطبيق الأكثر قابلية للدفاع عنه وقيمة لمقاييس التعقيد، أكثر بكثير من استخدامها كبوابة نجاح/فشل مطلقة.
حدِّد العتبات نسبة لقاعدة كودك الخاصة، لا رقمًا عالميًا
عتبات التعقيد المطلقة المُستعارَة بلا انتقاد من العرف الصناعي (درجة تعقيد عشرة قاعدة عامة شائعة الاقتباس) يمكن أن تكون إما متساهلة جدًا أو صارمة جدًا اعتمادًا على مجالك: قد يكون لدى مُحلِّل نحوي أو محرك قواعد تعقيد أساسي أعلى مشروعًا من خدمة إنشاء/قراءة/تحديث/حذف نموذجية. عايِر عتباتك الخاصة مقابل التوزيع الفعلي لقاعدة كودك، وعامل خرق عتبة كمُحفِّز للنظر عن قرب، لا فشل بناء تلقائي، ما لم يختر فريقك عمدًا تلك السياسة الأكثر صرامة بوعي كامل بمفاضلاتها.
راقب التلاعب عبر التفكيك بدون تبسيط حقيقي
الطريقة الأكثر شيوعًا للتلاعب بدرجات التعقيد هي نمط الاستبدال من الموضوع 1.2 مُطبَّقًا على هذا المقياس تحديدًا: تقسيم دالة معقدة حقًا إلى عدة دوال أصغر تُسجِّل كل منها جيدًا بمفردها، بينما يبقى النظام الكلي صعب الفهم بنفس القدر، أو يصبح أحيانًا أصعب، لأن المنطق الآن مُبعثَر عبر ملفات أكثر بتسلسل أكثر بينها. اقرن مقاييس التعقيد بمراجعة نوعية لما إذا كان التفكيك قد وضّح الكود حقًا، أو ما إذا كان قد نقل التعقيد فقط إلى مكان لا يستطيع المقياس رؤيته فيه بعد الآن.
ميّز التعقيد الأساسي عن التعقيد العرضي قبل التصرف
قبل معاملة درجة تعقيد عالية كمشكلة يجب إصلاحها، اسأل ما إذا كانت المشكلة الأساسية تتطلب حقًا هذا العدد من المسارات المستقلة، منطق حساب كود ضريبي له بشكل مشروع فروع كثيرة، مثلًا، أو ما إذا كان التعقيد يأتي من أسباب قابلة للتجنب: شروط متداخلة بعمق يمكن تسطيحها، أو منطق مُكرَّر يمكن دمجه، أو حدود مسؤولية غير واضحة يمكن إعادة رسمها. الفئة الثانية فقط مشكلة جودة حقيقية ينبغي أن يدفعك هذا المقياس لإصلاحها.
تتبّع الاتجاه والقيم الشاذة، لا متوسط لقطة فقط
درجة تعقيد متوسطة على مستوى قاعدة الكود بأكملها تتحرك قليلًا نادرًا ما تكون قابلة للتصرف بمفردها؛ تعقيد ملف محدد يرتفع بشكل حاد عبر عدة تغييرات، أو عدد صغير من القيم الشاذة المتطرفة في قاعدة كود تتصرف بشكل جيد لولا ذلك، إشارات أكثر فائدة بكثير. تتبّع كلًا من الاتجاه عبر الزمن وذيل القيم الشاذة، واستخدمهما لإطلاق تحقيق محدد ومُستهدَف بدلًا من مبادرة تقليل تعقيد واسعة وغير مُركَّزة.
المفاضلات: الإيجابيات والسلبيات
| النهج | الإيجابيات | السلبيات |
|---|---|---|
| عتبة عالمية مطلقة | بسيطة، ثابتة، سهلة الأتمتة | تتجاهل اختلافات مجال مشروعة؛ يمكن التلاعب بها عبر التفكيك |
| عتبة نسبية لقاعدة الكود | معايرة أفضل للسياق الفعلي | تتطلب إعدادًا أكثر وإعادة معايرة دورية |
| التعقيد كبوابة بناء آلية | يفرض اتساقًا بدون عبء مراجعة بشرية | يمكن أن يمنع كودًا معقدًا بشكل مشروع لكنه مُصمَّم جيدًا، أو يُكافئ تفكيكًا مُعتَّمًا عليه |
| التعقيد كإشارة فرز للمراجعة البشرية | يكتشف مشكلات جودة حقيقية سيفوتها التفكيك وحده | يتطلب وقت مراجعة بشرية أكثر من بوابة آلية كاملة |
التوتر المركزي هو الأتمتة مقابل الحكم. بوابة تعقيد آلية بالكامل رخيصة الفرض وثابتة، لكنها يمكن أن تمنع كودًا معقدًا ومُصمَّمًا جيدًا بشكل مشروع وتُكافئ تفكيكًا سطحيًا يتلاعب بالدرجة بدون تبسيط أي شيء حقًا. حُلّ التوتر باستخدام تحليل تعقيد آلي لكشف مرشحين للمراجعة، وحجز الحكم الفعلي، هل هذا التعقيد أساسي أم عرضي، هل وضّحت إعادة الهيكلة هذه حقًا أم نقلت التعقيد فقط، لمراجع بشري بدلًا من بوابة آلية صارمة وحدها.
أسئلة للنقاش مع فريقك
هل عتبات تعقيدنا معايرة لتوزيع قاعدة كودنا الفعلي، أم مُستعارة بلا انتقاد من عرف صناعي عام؟ اسحب توزيع تعقيد قاعدة كودك الحقيقي وتحقق مما إذا كانت عتباتك الحالية منطقية مقابله، بدلًا من افتراض أن رقمًا شائع الاقتباس ينطبق عالميًا على مجالك.
هل رأينا يومًا دالة مُقسَّمة إلى عدة دوال أصغر بدون أن يصبح الكود الناتج أسهل فهمًا فعليًا؟ هذه أوضح علامة على نمط التلاعب بالتفكيك الذي يحذّر منه هذا الموضوع. انظر إلى إعادة هيكلة حديثة مدفوعة أساسًا بدرجة تعقيد وقيّم بصدق ما إذا كانت قد حسّنت الفهم الحقيقي.
أين في قاعدة كودنا التعقيد أساسي للمشكلة، وأين هو عرضي وقابل للإصلاح؟ استعرض أعلى قيمك الشاذة تعقيدًا وصنّفها إلى هاتين الفئتين صراحة، إذ الفئة الثانية فقط تمثل مشكلة جودة حقيقية وقابلة للتصرف.
هل نستخدم مقاييس التعقيد لفرز جهد المراجعة، أم كبوابة آلية صارمة بدون أي حكم بشري متضمَّن؟ ناقش ما إذا كان نهج إنفاذك الحالي يترك مجالًا للتمييز بين الأساسي والعرضي الذي يوصي به هذا الموضوع، أو ما إذا كان يعامل كل خرق بشكل متطابق بغض النظر عن السياق.
هل استُخدِمت درجة تعقيد يومًا، حتى بشكل غير رسمي، للحكم على جودة عمل مهندس فردي؟ هذا يخاطر بنفس فخ التقييم الفردي الذي يحذّر منه الموضوع 3.4 لمقاييس النشاط، مُطبَّقًا هنا على مقاييس الكود بدلًا من ذلك، ويدعو لنفس استجابة التلاعب.
كيف يبدو اتجاه تعقيدنا خلال العام الماضي لأكثر ملفاتنا أهمية وأكثرها تغييرًا؟ ادمج هذا مع تحليل التغيّر والنقاط الساخنة من الموضوع 4.3، إذ ملف عالي التعقيد ومتغيّر بشكل متكرر يستحق اهتمامًا قبل ملف معقد لكن نادرًا ما يُلمَس بكثير.
منظور القطاع
الشركات الناشئة. مقاييس التعقيد عادة أقل إلحاحًا بهذا الحجم؛ حجم قاعدة الكود صغير بما يكفي بحيث تحل الألفة غير الرسمية غالبًا محل القياس الرسمي. العادة التي تستحق التبني مبكرًا هي ببساطة تشغيل فحص تعقيد أحيانًا لاكتشاف ملف محدد يصبح غير قابل للإدارة بهدوء قبل أن ينمو الفريق لدرجة يتعذر فيها الملاحظة بشكل غير رسمي.
الشركات الصغيرة. معظم أدوات التحليل الساكن الحديثة تُبلِّغ عن مقاييس التعقيد كجزء من إعداد فحص أوسع ومجاني أو منخفض التكلفة؛ استخدم المُخرَج كإشارة فرز دورية بدلًا من الاستثمار في أدوات مخصصة. ركّز الاهتمام على ملفاتك الأكثر تعديلًا أولًا.
المؤسسات الكبرى. مقاييس التعقيد بهذا الحجم أكثر قيمة مقترنة ببيانات التغيّر (الموضوع 4.3) لتحديد أولويات استثمار إعادة الهيكلة عبر قاعدة كود أكبر من أن يستطلعها أي فرد يدويًا. عايِر العتبات لكل خدمة أو مجال بدلًا من تطبيق رقم واحد على مستوى المنظمة، إذ يتفاوت التعقيد المشروع بشكل كبير عبر أنواع أنظمة مختلفة.
الحكومة. الأنظمة الحكومية طويلة العمر غالبًا ما تُراكِم تعقيدًا تدريجيًا عبر سنوات أو عقود من تغييرات متطلبات تدريجية، ويمكن أن يكون تدقيق تعقيد أداة مقنعة وملموسة لتبرير استثمار تحديث أو إعادة هيكلة لأصحاب مصلحة قد يرون النظام بخلاف ذلك ببساطة “يعمل” وبالتالي لا يستحق الاستثمار.
أمثلة
المؤسسات الكبرى. شغّلت شركة معالجة مدفوعات تدقيق تعقيد على مستوى قاعدة الكود بأكملها للمرة الأولى ووجدت دالة واحدة للتحقق من صحة المعاملات بدرجة تعقيد دوري أكثر من عشرة أضعاف وسيط قاعدة الكود. وجد التحقيق أن التعقيد كان عرضيًا بالكامل تقريبًا: سنوات من معالجة حالات خاصة مُضافة تدريجيًا لمزودي دفع محددين تراكمت إلى شروط متداخلة بعمق يمكن إعادة هيكلتها إلى نمط استراتيجية أنظف يفصل منطق كل مزود. أعادة الهيكلة، مُحدَّدة أولويتها مباشرة لأن تدقيق التعقيد حدّدها كأعلى هدف قيمة في قاعدة الكود، خفّضت درجة تعقيد الدالة بأكثر من 80%، والأهم، خفّضت معدل العيوب في ذلك المسار المحدد للكود بشكل قابل للقياس خلال الربعين التاليين.
الحكومة. سجّل محرك حساب إعانات عمره عقود لهيئة ضرائب درجات عالية جدًا في مقاييس التعقيد عبر كل دالة تقريبًا، مما دفع افتراضًا أوليًا بأن النظام بأكمله يحتاج إعادة كتابة من الصفر. وجدت مراجعة أقرب، دالة تلو أخرى، تميّز الأساسي من العرضي، أن معظم التعقيد يعكس حقًا القواعد القانونية الأساسية، التي كان لديها فعلًا هذا العدد من الفروع المشروعة والحالات الخاصة التي يُلزِمها القانون، بينما جاءت مجموعة فرعية أصغر من تكرار قابل للتجنب عبر مسارات حساب مشابهة. استهدف الفريق فقط المجموعة الفرعية للتعقيد العرضي لإعادة الهيكلة، متجنبًا إعادة كتابة كاملة مكلفة ومحفوفة بالمخاطر بينما حسّن مع ذلك بشكل ذي معنى أكثر مجالات النظام إشكالية حقًا.
الحالة التجارية: الدوافع والعائد على الاستثمار وإجمالي تكلفة الملكية
العائد على استخدام مقاييس التعقيد جيدًا هو استثمار إعادة هيكلة مُستهدَف وعالي القيمة: يُظهر مثال شركة المدفوعات أعلاه إصلاحًا واحدًا ومُستهدَفًا جيدًا، حُدِّد عبر تحليل التعقيد، خفّض العيوب بشكل قابل للقياس في بالضبط أخطر مسار كود، بكسر من تكلفة مبادرة إعادة هيكلة واسعة وغير مُستهدَفة كانت ستتطلبها.
إجمالي تكلفة الملكية منخفض: تحسب معظم سلاسل أدوات التطوير الحديثة مقاييس التعقيد تلقائيًا كجزء من التحليل الساكن (الموضوع 4.4)، والاستثمار الحقيقي هو وقت الحكم البشري لتفسير النتائج بشكل صحيح، تمييز الأساسي من العرضي واكتشاف التلاعب بالتفكيك، بدلًا من أي تكلفة أدوات جديدة كبيرة.
الأنماط المضادة والمزالق
- معاملة درجة تعقيد كحكم جودة مباشر: تقيس خاصية محددة واحدة، لا جودة الكود الإجمالية.
- تقسيم دالة للتلاعب بالدرجة بدون تبسيط حقيقي: نمط التلاعب بالتفكيك الذي يُسمِّيه هذا الموضوع تحديدًا.
- تطبيق عتبة عالمية بدون معايرة لقاعدة كودك الخاصة: يُنتج إنفاذًا إما متساهلًا جدًا أو صارمًا جدًا اعتمادًا على المجال.
- استخدام مقاييس التعقيد لتقييم المهندسين فرديًا: يدعو للتلاعب ويُسيء تطبيق مقياس مُصمَّم للفرز، لا الحكم.
- معاملة كل التعقيد كقابل للإصلاح بالتساوي: التعقيد الأساسي من مشكلة صعبة حقًا ليس عيبًا يجب القضاء عليه.
- تجاهل الاتجاه والقيم الشاذة لصالح متوسط ثابت على مستوى قاعدة الكود: يفوّت الإشارة الأكثر قابلية للتصرف التي توفرها عائلة المقاييس هذه.
نموذج النضج
- المستوى 1، البدء: لا يُقاس التعقيد، أو يُقاس بعتبة عالمية عامة وغير مفحوصة تُطبَّق بلا انتقاد.
- المستوى 2، التطوير: تُجمَع مقاييس التعقيد لكن نادرًا ما يُتصرَّف بناءً عليها، ولا تمييز بين التعقيد الأساسي والعرضي.
- المستوى 3، التوحيد القياسي: تُعايَر العتبات لتوزيع قاعدة الكود نفسها، وتقود مقاييس التعقيد باتساق فرز المراجعة وإعادة الهيكلة على مستوى المنظمة.
- المستوى 4، الإدارة: تُراقَب اتجاهات التعقيد والقيم الشاذة بنشاط وتُدمَج مع بيانات التغيّر (الموضوع 4.3) لتحديد أولويات استثمار إعادة الهيكلة؛ يُراقَب التلاعب بالتفكيك بنشاط.
- المستوى 5، التنسيق الشامل: تستطيع المنظمة الإشارة إلى تحسينات محددة وقابلة للقياس في معدل العيوب تعود مباشرة إلى استثمار إعادة هيكلة مُستنيَر بالتعقيد، وبيانات التعقيد مدخل روتيني وموثوق لقرارات استثمار الهندسة.
أفكار للنقاش
- ما أكثر دالة أو ملف تعقيدًا لدينا، وهل تعقيده أساسي أم عرضي؟
- هل تلاعبنا يومًا بدرجة تعقيد عبر التفكيك بدون تبسيط حقيقي؟
- هل عتباتنا معايرة لقاعدة كودنا الخاصة، أم مُستعارة بلا انتقاد؟
- أين يتداخل التعقيد العالي مع التغيّر العالي في قاعدة كودنا الآن؟
- هل أثرت بيانات التعقيد يومًا في قرار استثمار إعادة هيكلة، أم تجلس غير مُستخدَمة؟
أهم الاستنتاجات
- تتنبأ مقاييس التعقيد مثل التعقيد الدوري بصعوبة الاختبار والعيوب؛ لا تقيس جودة الكود الإجمالية مباشرة.
- ميّز التعقيد الأساسي (من مشكلة صعبة حقًا) عن التعقيد العرضي (قابل للتجنب عبر تصميم أفضل) قبل التصرف بناءً على درجة عالية.
- راقب التلاعب بالتفكيك: تقسيم الكود لتخفيض درجة بدون تبسيط أي شيء حقًا.
- استخدم مقاييس التعقيد للفرز، موجِّهة جهد المراجعة البشرية وإعادة الهيكلة، لا كبطاقة تسجيل فردية أو بوابة آلية صارمة.
- عايِر العتبات لـتوزيع قاعدة كودك الخاصة، وتتبّع الاتجاه والقيم الشاذة، لا متوسطًا ثابتًا فقط.
المراجع وقراءات إضافية
- McCabe, Thomas J., “A Complexity Measure,” IEEE Transactions on Software Engineering (1976): ورقة التعقيد الدوري الأصلية.
- Code Complete، بقلم Steve McConnell (توجيه عملي لإدارة التعقيد في بناء البرمجيات).
- Working Effectively with Legacy Code، بقلم Michael Feathers (تقنيات لتقليل التعقيد بأمان في كود موروث وصعب التغيير).
- Campbell, G. Ann, “Cognitive Complexity: A New Way of Measuring Understandability” (SonarSource, 2018): مقياس التعقيد المعرفي وتمييزه عن التعقيد الدوري.