Skip to content

جودة الكود وإعادة البناء

مقدمة

هل يكفي أن يعمل الكود فحسب؟ ربما كتبت كودًا يؤدي الوظيفة، لكن بعد أسبوعين لا تستطيع حتى أنت فهمه. أو غادر أحد أعضاء الفريق وترك وراءه كودًا "لا يفهمه إلا الله وهو".

سيساعدك هذا الفصل على فهم ما هو الكود الجيد، وكيفية التعرف على الكود السيئ، وكيفية تحسينه بأمان.

ماذا ستتعلم في هذه المقالة؟

الفصلالمحتوىالمفهوم الأساسي
الفصل 1روائح الكود السيئةالتعرف على المشاكل الشائعة
الفصل 2تقنيات إعادة البناءتحسين الكود بأمان
الفصل 3مراجعة الكودضمان الجودة في عمل الفريق
الفصل 4قياس الجودةقياس صحة الكود بالبيانات

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


0. نظرة عامة: دورة حياة الكود

في تطوير البرمجيات، هناك حقيقة غالبًا ما تُتجاهل: يُقرأ الكود مرات أكثر بكثير مما يُكتب.

يمر جزء من الكود منذ نشأته حتى تقاعده تقريبًا بهذه الرحلة:

حياة الكود

  • مرحلة الكتابة: يكتب المطور النسخة الأولى، تعمل الوظيفة، تنجح الاختبارات.
  • مرحلة المراجعة: يقرأ أعضاء الفريق الكود ويقدمون اقتراحات للتحسين.
  • مرحلة الصيانة: إصلاح الأخطاء، إضافة ميزات، التكيف مع المتطلبات الجديدة — تستحوذ هذه المرحلة على أكثر من 80% من دورة حياة الكود.
  • مرحلة إعادة البناء: عندما يصبح الكود صعب الصيانة، يحتاج إلى تحسين هيكله الداخلي دون تغيير سلوكه الخارجي.
  • مرحلة التقاعد: تتطور التكنولوجيا، ويُستبدل الكود القديم بحلول جديدة.

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


1. روائح الكود السيئة: التعرف على المشاكل الشائعة

1.1 ما هي روائح الكود السيئة؟

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

من خلال المكون التفاعلي التالي، تعرف على أكثر روائح الكود شيوعًا:

Code Smell Detector - click to switch examples
Problem code
function processOrder(order) {
  // Validate order... (20 lines)
  // Calculate price... (15 lines)
  // Check inventory... (10 lines)
  // Send notification... (15 lines)
  // Update database... (10 lines)
  // Generate report... (10 lines)
  // 80+ lines in total!
}

📏 Long function

A function exceeds 50 lines, does too many things, and becomes hard to understand and test.

Improvement:Split the large function into focused functions such as validateOrder(), calculatePrice(), and checkInventory().

1.2 قائمة بالروائح السيئة الشائعة

الرائحة السيئةالأعراضالخطر
دوال طويلة جدًادوال تتجاوز 50 سطرًاصعبة الفهم والاختبار وإعادة الاستخدام
الأرقام السحريةكتابة 86400000 مباشرة في الكودالمعنى غير واضح، سهل التغافل عند التعديل
كود مكررمنطق مشابه يظهر في عدة أماكنعند التعديل يجب مزامنة عدة مواقع، سهل النسيان
تداخل عميقأكثر من 3 مستويات من if/forالمنطق كمتاهة، صعب التتبع
قائمة معاملات طويلةأكثر من 4 معاملات في الدالةصعبة الاستدعاء، سهل الخطأ في الترتيب
الفئة الشاملة (God Class)فئة/وحدة واحدة تفعل أشياء كثيرةمسؤوليات غير واضحة، لمس شيء يؤثر على الكل

بصيرة أساسية

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


2. تقنيات إعادة البناء: تحسين الكود بأمان

2.1 ما هي إعادة البناء؟

إعادة البناء (Refactoring) لها تعريف دقيق جدًا: تحسين الهيكل الداخلي للكود دون تغيير سلوكه الخارجي.

الكلمة المفتاحية هي "دون تغيير السلوك الخارجي". إعادة البناء ليست إعادة كتابة، وليست إضافة ميزات، وليست إصلاح أخطاء. إنها "ترتيب وتنظيم" داخلي للكود.

من خلال المكون التالي، قارن التغييرات قبل وبعد عدة تقنيات إعادة بناء شائعة:

Refactoring technique comparison - choose a technique to compare before and after
Extract Function: move a code block out of a large function into a clearly named new function.
Before
function printReport(invoice) {
  console.log("=== Invoice ===")
  // Calculate total
  let total = 0
  for (let item of invoice.items) {
    total += item.price * item.qty
  }
  console.log(`Total: ${total}`)
}
After
function printReport(invoice) {
  console.log("=== Invoice ===")
  const total = calcTotal(invoice.items)
  console.log(`Total: ${total}`)
}

function calcTotal(items) {
  return items.reduce(
    (s, i) => s + i.price * i.qty, 0
  )
}
Key point:Extract Function is one of the most common refactorings. A good function name is the best comment.

2.2 تقنيات إعادة البناء الأكثر استخدامًا

استخراج دالة (Extract Function)

هذه هي تقنية إعادة البناء الأكثر استخدامًا. عندما يمكن تلخيص جزء من الكود باسم ذي معنى، يجب استخراجه كدالة.

javascript
// قبل إعادة البناء
function printReport(data) {
  // حساب الإجمالي
  let total = 0
  for (const item of data.items) {
    total += item.price * item.qty
  }
  // طباعة...
}

// بعد إعادة البناء
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price * item.qty, 0)
}

function printReport(data) {
  const total = calculateTotal(data.items)
  // طباعة...
}

إعادة التسمية (Rename)

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

javascript
// قبل إعادة البناء
const d = new Date() - startTime  // الوقت المنقضي
const arr = users.filter(u => u.a) // المستخدمون النشطون

// بعد إعادة البناء
const elapsedMs = new Date() - startTime
const activeUsers = users.filter(user => user.isActive)

استبدال التداخل بشرط حراسة (Replace Nested Conditional with Guard Clauses)

javascript
// قبل إعادة البناء
function getPayAmount(employee) {
  if (employee.isSeparated) {
    return { amount: 0 }
  } else {
    if (employee.isRetired) {
      return { amount: employee.pension }
    } else {
      return { amount: employee.salary }
    }
  }
}

// بعد إعادة البناء
function getPayAmount(employee) {
  if (employee.isSeparated) return { amount: 0 }
  if (employee.isRetired) return { amount: employee.pension }
  return { amount: employee.salary }
}

شبكة أمان إعادة البناء

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


3. مراجعة الكود: ضمان الجودة في عمل الفريق

3.1 لماذا نحتاج مراجعة الكود؟

مراجعة الكود (Code Review) هي واحدة من أكثر طرق ضمان الجودة فعالية في الفريق. قيمتها لا تكمن فقط في اكتشاف الأخطاء، بل أيضًا في:

  • مشاركة المعرفة: يتعرف أعضاء الفريق على كود بعضهم البعض، مما يقلل "عامل الحافلة" (إذا صُدم شخص بحافلة، هل يمكن أن يستمر المشروع؟)
  • توحيد الأسلوب: من خلال المراجعة، تتشكل تدريجيًا اتفاقيات البرمجة الخاصة بالفريق
  • اكتشاف مشاكل التصميم مبكرًا: ما هو أصعب في الإصلاح من الأخطاء هو القرارات المعمارية السيئة
  • التعلم المتبادل: قراءة كود الآخرين هي طريق مختصر لتحسين مهارات البرمجة

3.2 ماذا نراجع؟

البُعدنقاط الاهتمام
الصحةهل المنطق صحيح؟ هل عُولجت الحالات الحدية؟
قابلية القراءةهل الأسماء واضحة؟ هل الهيكل سهل الفهم؟
الأمانهل هناك خطر حقن؟ هل البيانات الحساسة مكشوفة؟
الأداءهل هناك مشاكل أداء واضحة؟ استعلامات N+1؟
الاختباراتهل هناك اختبارات مقابلة؟ هل غطت المسارات الحرجة؟

3.3 آداب المراجعة

مراجعة الكود الجيدة هي مناقشة حول الكود، وليست نقدًا للأشخاص:

  • استخدم "نحن" بدلاً من "أنت": "أنت أخطأت هنا" → "هنا يمكننا النظر في استخدام شرط حراسة"
  • اسأل بدلاً من أن تأمر: "غيّره إلى const" → "هل يُعاد تعيين هذا المتغير لاحقًا؟ إذا لا، فاستخدام const أكثر أمانًا"
  • قدّم الأسباب: لا تقل فقط "سيء"، بل قل "لماذا هو سيء" و"كيف يمكن تحسينه"

4. قياس جودة الكود

4.1 التعقيد الحلقي

التعقيد الحلقي (Cyclomatic Complexity) يقيس عدد المسارات المستقلة في الكود. كل if، for، case، &&، || يزيد التعقيد.

التعقيدالتقييمالتوصية
1-10بسيطسهل الفهم والاختبار
11-20متوسطفكر في التقسيم
21-50معقديجب إعادة البناء
50+غير قابل للصيانةإعادة بناء عاجلة

4.2 تغطية الكود

تغطية الكود تقيس نسبة الكود الذي تنفذه الاختبارات. المقاييس الشائعة:

  • تغطية الأسطر: نسبة أسطر الكود المنفذة من إجمالي الأسطر
  • تغطية الفروع: نسبة الفروع الشرطية المنفذة من إجمالي الفروع

فخ التغطية

80% تغطية لا تعني أن جودة الكود جيدة. التغطية تخبرك فقط "أي كود لم يُختبر"، ولا يمكنها إخبارك "هل الاختبارات ذات معنى". اختبار يؤكد فقط expect(true).toBe(true) يمكن أن يزيد التغطية لكنه بلا قيمة.

4.3 أدوات عملية

الأداةالاستخدام
ESLintتحليل ثابت لـ JavaScript/TypeScript
Prettierتنسيق الكود، توحيد الأسلوب
SonarQubeمنصة شاملة لجودة الكود
HuskyGit hooks، فحوصات تلقائية قبل الالتزام

5. دعم الذكاء الاصطناعي: تحسين جودة الكود بالنماذج اللغوية الكبيرة

أصبحت النماذج اللغوية الكبيرة عملية جدًا في مجال جودة الكود. يمكنها أن تعمل كـ "مراجع كود متاح على مدار الساعة".

5.1 التعرف على روائح الكود السيئة

Prompt:

يرجى مراجعة الكود التالي والتعرف على روائح الكود السيئة (Code Smells)، بما في ذلك على سبيل المثال لا الحصر:
دوال طويلة جدًا، أرقام سحرية، كود مكرر، تداخل عميق، قوائم معاملات طويلة.
لكل مشكلة، حدد الموقع، وصف المشكلة، وقدم اقتراحات للتحسين.

[الصق الكود الخاص بك]

5.2 إعادة البناء التلقائية

Prompt:

يرجى إعادة بناء الكود التالي وفقًا للمتطلبات التالية:
1. عدم تغيير السلوك الخارجي
2. استخدام تقنيات مثل استخراج الدوال واستبدال التداخل بشروط حراسة
3. تحسين التسمية، إزالة الأرقام السحرية
4. شرح سبب كل خطوة من خطوات إعادة البناء

[الصق الكود الخاص بك]

5.3 محاكاة مراجعة الكود

Prompt:

يرجى مراجعة هذا الكود من منظور مطور خبير، مع تقديم ملاحظات في الأبعاد التالية:
- الصحة: هل هناك أخطاء في المنطق؟ هل عُولجت الحالات الحدية؟
- قابلية القراءة: هل الأسماء واضحة؟ هل الهيكل سهل الفهم؟
- الأداء: هل هناك مشاكل أداء واضحة؟
- الأمان: هل هناك خطر حقن أو تسريب بيانات؟
استخدم نبرة "اقتراح" بدلاً من "أمر"، وقدم خطط تحسين.

[الصق الكود الخاص بك]

نصائح استخدام الذكاء الاصطناعي

اقتراحات إعادة البناء من الذكاء الاصطناعي تحتاج إلى تحقق منك شخصيًا — شغّل الاختبارات للتأكد من عدم تغير السلوك. تعامل مع الذكاء الاصطناعي كـ "زميل يقدم اقتراحات"، وليس "سلطة يجب إطاعتها بلا قيد".


6. الخلاصة

في هذه الرحلة، من التعرف على المشاكل إلى حلها، بنينا نظامًا متكاملًا لتحسين جودة الكود:

  1. التعرف: تعلم اكتشاف روائح الكود السيئة ومعرفة أين يحتاج التحسين
  2. إعادة البناء: إتقان تقنيات إعادة البناء الآمنة، مع التحسين بخطوات صغيرة تحت حماية الاختبارات
  3. التعاون: من خلال مراجعة الكود، يجعل الفريق الحفاظ على جودة الكود مسؤولية جماعية
  4. القياس: استخدام مقاييس موضوعية لتتبع صحة الكود

تأمل أخير

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


قراءات إضافية

  • كتاب كلاسيكي: Refactoring: Improving the Design of Existing Code لمارتن فاولر هو إنجيل هذا المجال.
  • فن الكود النظيف: Clean Code لروبرت سي. مارتن يقدم العديد من مبادئ البرمجة العملية.
  • أدوات عملية: حاول تكوين ESLint + Prettier + Husky في مشروعك لتجربة ضمان جودة الكود الآلي.
  • مراجعة الكود: إرشادات مراجعة الكود من جوجل هي معيار الصناعة وتستحق الدراسة.