كوبي بيست في تطوير التطبيقات — ما هو، ولماذا هو خطير، وكيف تتجنبه

المؤلف: IT Sectr نُشر: 2026-07-27 وقت القراءة: 10 دق

الكوبي بيست (نسخ-لصق) هو ممارسة نسخ أجزاء من الكود من مكان إلى آخر دون تكييفها مع السياق الجديد. في أغلب الأحيان، ينسخ المطور كتلة من وحدة موجودة، ويجري تعديلات طفيفة، ويلصقها في وحدة جديدة — مع الأخطاء والتعليقات القديمة والتبعيات غير الضرورية. وفقًا لـ TIOBE Code Quality Survey (2025)، تحتوي المشاريع ذات المستوى العالي من الكوبي بيست على ثلاثة أضعاف العيوب لكل ألف سطر من الكود مقارنة بالمشاريع ذات التجريد الموحد. تكرار الكود هو المصدر الرئيسي للدين التقني: كل نسخة تتطلب صيانة منفصلة، وإصلاح خطأ في مكان واحد لا يضمن إصلاحه في الأماكن الأخرى.

النقاط الرئيسية

  • الكوبي بيست — نسخ الكود دون فهم أو تكييف، المصدر الرئيسي للدين التقني.
  • خطر الكوبي بيست: الأخطاء تتضاعف عبر المشروع، إصلاح نسخة واحدة لا يصلح البقية.
  • DRY (Don't Repeat Yourself) — المبدأ الأساسي الذي يمنع الكوبي بيست.
  • أدوات اكتشاف التكرار: PMD CPD، SonarQube، ESLint مع قواعد التكرار.
  • إعادة هيكلة الكوبي بيست — استخراج الكود المشترك إلى دالة أو كلاس أو مكتبة.

ما هو الكوبي بيست؟

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

ينقسم الكوبي بيست إلى نوعين: متعمد وعرضي. المتعمد — عندما ينسخ المطور الكود عن عمد مع خطة لإعادة هيكلته لاحقًا (لكن الخطة غالبًا ما تُهمل). العرضي — عندما ينشأ التكرار دون أن يلاحظه أحد، على سبيل المثال، يكتب مطوران بشكل مستقل نفس المنطق لشاشات مختلفة.

وفقًا لتقرير SonarQube State of Clean Code (2025)، يشكل الكود المكرر في المتوسط 12–18 بالمائة من إجمالي حجم الكود في المشاريع التجارية. في الوقت نفسه، تكلفة إصلاح خطأ في كود مكرر أعلى بـ 2.5 مرة من الكود ذي التنفيذ الواحد، لأن المطور يجب أن يجد ويصلح جميع النسخ.

الأداة الرئيسية ضد الكوبي بيست هي مبدأ DRY (Don't Repeat Yourself). ومع ذلك، فإن التطبيق المطلق لـ DRY خطير أيضًا: أحيانًا يكون النسخ مبررًا عندما يجب أن تتطور نسختان بشكل مستقل عن بعضهما البعض. من المهم التمييز بين «التكرار العرضي» (الذي يجب إزالته) و«التكرار الضروري» (الذي يجب توثيقه).

لماذا الكوبي بيست خطير

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

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

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

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

لماذا ينسخ المطورون الكود

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

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

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

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

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

أدوات اكتشاف التكرار

يتم الكشف عن الكوبي بيست بواسطة محللات آلية تقارن أجزاء الكود وتحدد التطابقات فوق عتبة معينة. تعمل أفضل الأدوات على مستوى AST (شجرة التركيب المجرد) وتتجاهل التنسيق وأسماء المتغيرات والتعليقات.

PMD CPD (Copy-Paste Detector) هو الأداة الأكثر شيوعًا لـ Java وKotlin وSwift وJavaScript وPython وC++. يحلل CPD رموز الكود المصدري ويجد التكرارات الأطول من عدد أدنى محدد من الرموز (الافتراضي 100). يعد تكوين العتبة مفتاحًا للحصول على نتائج جيدة: عتبة منخفضة جدًا تعطي العديد من النتائج الإيجابية الخاطئة (أنماط شائعة مثل الاستيرادات)، بينما عتبة عالية جدًا تفوت التكرارات الحقيقية.

تشغيل PMD CPD عبر Gradle

groovy
plugins {
    id 'pmd'
}

pmd {
    toolVersion = '7.0.0'
    ruleSetFiles = files("pmd-rules.xml")
}

tasks.register('cpd') {
    doLast {
        exec {
            workingDir = projectDir
            commandLine 'cpd',
                '--minimum-tokens', '75',
                '--language', 'kotlin',
                '--files', 'src/main/kotlin',
                '--format', 'xml',
                '--failOnViolation', 'true'
        }
    }
}

SonarQube يدمج كاشف التكرار مباشرة في Quality Gate. تعرض قاعدة Duplicated Blocks (%) النسبة المئوية للكود المكرر. تعتبر عتبة 5 بالمائة صحية للمشاريع التجارية. تجاوزها يمنع الترقية إلى فرع الإصدار. يقوم SonarQube أيضًا بتجميع التكرارات حسب النوع: التطابقات التامة والنسخ الهيكلية (مع معرفات معاد تسميتها).

بالنسبة لـ JavaScript وTypeScript، يتم اكتشاف التكرارات باستخدام ESLint مع البرنامج المساعد eslint-plugin-sonarjs (قاعدة no-duplicate-string) والأداة المساعدة jscpd التي تدعم أكثر من 150 لغة. jscpd مفيد بشكل خاص للمستودعات الأحادية: فهو يجد التكرارات بين الحزم، وليس فقط داخل وحدة واحدة.

استراتيجيات إعادة هيكلة الكود المكرر

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

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

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

swift
// before - two copies of the same UITableViewController
class UserListController: UITableViewController {
    private let viewModel = UserListViewModel()
    // 40 lines of code
}

class ProductListController: UITableViewController {
    private let viewModel = ProductListViewModel()
    // same 40 lines but with Product instead of User
}

// after - generic base class shared
class ListViewController<T: ListViewModel>: UITableViewController {
    let viewModel: T
    // 40 lines of code - once only

    init(viewModel: T) {
        self.viewModel = viewModel
        super.init(style: .plain)
    }
}

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

الوقاية من الكوبي بيست على مستوى الفريق

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

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

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

التدبير الثالث هو الأتمتة في CI/CD. أضف خطوة التحقق من الكود المكرر إلى خط الأنابيب (PMD CPD، jscpd، SonarQube). تجاوز العتبة يؤدي إلى فشل البناء. لا يمكن للمطور دمج PR يزيد من نسبة الكوبي بيست فوق المستوى المسموح به. هذا ينقل المسؤولية من مراجعة الكود إلى الأتمتة ويضمن عدم تفويت أي تكرار.

عزز ثقافة «تنفيذ واحد — مكان واحد.» إذا رأيت فرصة لإعادة الاستخدام — لا تؤجل إعادة الهيكلة لوقت لاحق. كل كوبي بيست يُترك «لوقت لاحق» يتضاعف ويتحول إلى دين تقني لا يمكن السيطرة عليه.

الأسئلة الشائعة

هل الكوبي بيست دائمًا سيء؟

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

كيف نميز الكوبي بيست عن إعادة الاستخدام الصحي؟

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

ما الأدوات التي تكتشف الكوبي بيست في مشاريع iOS؟

PMD CPD يدعم Swift وObjective-C. بالنسبة لـ Xcode، توجد إضافات مثل SwiftCop وكاشف تكرار مدمج في AppCode. يحلل SonarQube أيضًا مشاريع Swift، ويعرض الكتل المكررة مباشرة في طلبات السحب.

ماذا أفعل إذا كان الكوبي بيست موجودًا بالفعل ولا يوجد وقت لإعادة الهيكلة؟

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

هل تساعد أدوات الذكاء الاصطناعي في اكتشاف الكوبي بيست؟

نعم، يمكن للمساعدين الحديثين بالذكاء الاصطناعي (GitHub Copilot، Codeium) تحليل السياق واقتراح استخراج الكود المشترك عند اكتشاف أنماط متكررة. ومع ذلك، فإنها لا تحل محل المحللات الآلية — استخدم Copilot لـ الوقاية، وCPD / SonarQube للاكتشاف.

الخلاصة

  • الكوبي بيست — تكرار الكود عن طريق النسخ دون تكييف، المصدر الرئيسي للدين التقني.
  • انتشار الأخطاء: إصلاح نسخة واحدة لا يصلح البقية، تنتشر العيوب عبر المشروع.
  • الأسباب الرئيسية: المواعيد النهائية، عدم وجود تجريد مشترك، الخوف من كسر الكود العامل أثناء إعادة الهيكلة.
  • أدوات الكشف: PMD CPD، SonarQube، jscpd، ESLint sonarjs/no-duplicate-string، SwiftCop.
  • إعادة الهيكلة: استخراج الكود المشترك في دالة أو كلاس عام أو مكون مشترك مع ترميز الاختلافات كمعاملات.
  • الوقاية: مراجعة الكود مع فحص التكرار، مكتبة مكونات مشتركة، فحص CI للتكرارات.
  • القاعدة الثقافية: تنفيذ واحد — مكان واحد. قم بتوثيق التكرار الواعي وراقبه حسب الجدول الزمني.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا