تكرار الشيفرات (Duplicate Code)
توصيف المشكلة
التشابه (أو التطابق المطلق) بين مقطعين من الشيفرة في البرنامج.
أسبابها
- تحدث هذه المشكلة عندما يعمل أكثرُ من مبرمجٍ على كتابة أجزاءَ مختلفةٍ من نفس البرنامج وبنفس الوقت، فلا يدري أحدهم أنّ الشيفرة التي يكتبها قد سبقه بها مبرمجٌ آخر ومن الممكن استخدامها نفسها دون الحاجة لتكرارها.
- أو قد تنتُج عن وجود جزئين من الشيفرة مختلفين شكليًّا متماثلين ضمنيًا (يؤديان نفس المهمة)، ومن الصعب كشف هذا النوع من التكرار وعلاجه.
- قد يكون التكرار هادفًا ببعض الأحيان، كأن يكون بهدف الالتزام بالموعد النهائيّ (deadline) (وخاصّة إن كانت الشيفرة تعمل بشكلٍ صحيح)، فيغلبُ على المبرمجين المبتدئين حينئذٍ ميلُهم لنسخ ولصق الشيفرات بما يناسب البرنامج، أو قد يغالبهم الكسل فيتفادون إزالة الفوضى المنتشرة في الشيفرة.
وما الحل؟
- عند تكرار الشيفرة بأكثر من تابع (method) وبنفس الصنف (class) فالحل عندئذٍ بنقلها إلى تابعٍ مُخصّص وتبديل كل تكرارٍ لها إلى استدعاءات (calls) للتابع الجديد.
- إن كان التكرار في صنفين فرعيين (subclasses) وبنفس المستوى (level):
- عليك باستخراج تابعٍ (extract method) لكلا الصنفين، ثمّ رفع الحقول إلى الصنف الأعلى (pull up fields) وذلك لكافَّة الحقول المستخدمة في التابع.
- إن كان التكرار في الباني (constructor) فعليك برفع (نقل) ما يحتويه الباني إلى الباني في الصنف الأعلى (pull up constructor body).
- إن كان التكرار متشابهًا (غير متطابق كليًّا) فيُفيد استخدام تابع قالب النموذج (form template method).
- إن كان للتابعين نفس المهمة ولكن بالاعتماد على خوارزميتين مختلفتين فاختر الخوارزمية الأفضل، وطبّق تقنيّة استبدال الخوارزمية (substitute algorithm).
- إن كان التكرار في صنفين مختلفين:
- إن لم يكن الصنفان جزءًا من أيّ هيكليّة هرميّة (hierarchy) فالحلُّ باستخراج الصنف الأعلى (extract superclass) بهدف إنشاء صنفٍ أعلى وحيدٍ للصنفين يشمل المهام (functionality) بأكملها.
- إن كان من الصعب (أو المستحيل) إنشاءُ صنفٍ أعلى للصنفين، فالحلُّ بتطبيق استخراج الصنف (extract class) لأحدهما واستخدام الناتج عن ذلك في الصنف الآخر.
- عند وجود عددٍ كبيرٍ من التعابير الشرطيّة (conditional expressions) التي تنفِّذ الشيفرة ذاتها (تختلف فيما بينها بالشرط فقط) فيكون الحلُّ بدمجها جمعيًا في شرطٍ واحدٍ (راجع دمج التعابير الشرطيّة) وتخصيص تابعٍ (method) لوضع الشرط فيه بشكلٍ مستقلٍ مع تسمية هذا التابع باسمٍ معبِّر يُسهِّل فهم الشيفرة.
- إن كانت لجميع فروع التعبير الشرطيّ الشيفرة ذاتها، فيجب حينئذٍ نقل تلك الشيفرة المُتكرِّرة إلى ما قبل الشرط (راجع دمج الأجزاء الشرطيّة المُتكرِّرة).
إليك المزيد
سيُبسِّط دمجُ الشيفرات المُتكرِّرة بنيةَ البرنامج لتصبح الشيفرة أقصر، وما يميِّز الشيفرة البسيطة القصيرة أنها واضحةٌ وبتكلفةٍ أقلّ بما يخصّ الدعم (support).
تجاهل المشكلة
يكون التجاهل بحالات نادرة جدًا وذلك عندما تجعل إزالة التكرار الشيفرةَ أكثر غموضًا وصعوبةً.
انظر أيضًا
- استخراج التابع (extract method)
- رفع الحقول إلى الصنف الأعلى (pull up fields)
- رفع الباني إلى الصنف الأعلى (pull up constructor body)
- تابع قالب النموذج (form template method)
- استبدال الخوارزمية (substitute algorithm)
- استخراج الصنف (extract class)
- استخراج الصنف الأعلى (extract superclass)
- دمج التعابير الشرطيّة
- دمج الأجزاء الشرطيّة المُتكرِّرة