إعادة هيكلة الكود القديم بلغة JavaScript: من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا الكود القديم ليس حكماً بالإعدام

كل مطور يواجه عاجلاً أم آجلاً كوداً قديماً بلغة JavaScript. قد تكون نصوصاً ضخمة على Node.js كُتبت "على عجل" قبل 5 سنوات، أو دوال استدعاء متداخلة معقدة يخشى حتى المطورون الكبار لمسها. لكن إعادة هيكلة الكود القديم ليست مجرد "إعادة كتابة كل شيء من الصفر"، بل هي عمل منهجي لتحسين البنية دون تغيير السلوك الخارجي.

في هذه المقالة، سنشرح خطة خطوة بخطوة لإعادة الهيكلة بلغة JavaScript (Node.js): من التحليل والاختبار إلى تطبيق الأنماط الحديثة. ستتعلم كيفية تحويل "المستنقع" إلى كود قابل للصيانة باستخدام أمثلة واقعية.



1. تحليل ورسم خريطة الكود القديم

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



1.1. أدوات التحليل

بالنسبة لـ JavaScript/Node.js، استخدم:

  • ESLint مع قواعد complexity و max-lines — لاكتشاف الدوال المعقدة.
  • Plato أو CodeClimate — لتصور التعقيد الدوري.
  • Madge — لبناء رسم بياني لتبعيات الوحدات.


1.2. تحديد "روائح الكود"

المشاكل النموذجية للكود القديم في JS:

  • دوال يزيد طولها عن 100 سطر.
  • متغيرات عامة وتحوير الحالة.
  • جحيم الاستدعاءات (استدعاءات غير متزامنة متداخلة).
  • غياب النمطية (ملف واحد يزيد عن 2000 سطر).


// مثال على "رائحة": دالة تفعل كل شيء دفعة واحدةfunction processUserData(userId) {    // 100 سطر: تحقق، استعلام قاعدة بيانات، تنسيق، إرسال بريد إلكتروني    // ... يصعب اختباره وصيانته}


2. إعداد "شبكة الأمان": الاختبار

بدون اختبارات، إعادة الهيكلة هي "روليت روسية". أنشئ اختبارات التوصيف (اختبارات تثبت السلوك الحالي).



2.1. إضافة اختبارات الوحدة

استخدم Jest أو Mocha. ابدأ بالمسارات الحرجة:



// اختبار الدالة الحالية دون تغييرهاconst { processUserData } = require('./legacy');

describe('processUserData (قديم)', () => { it('يجب معالجة المستخدم بالمعرف 1', () => { const result = processUserData(1); expect(result).toHaveProperty('email'); expect(result.status).toBe('processed'); });});


2.2. اختبارات التكامل لـ Node.js

إذا كان الكود يتعامل مع قاعدة بيانات أو API، استخدم supertest لطلبات HTTP:



const request = require('supertest');const app = require('../app');

describe('POST /api/users', () => { it('يجب إنشاء مستخدم (سلوك قديم)', async () => { const res = await request(app) .post('/api/users') .send({ name: 'Test' }); expect(res.status).toBe(200); expect(res.body.id).toBeDefined(); });});


3. إعادة الهيكلة خطوة بخطوة: من الكتلة إلى الوحدات

سنقسم العملية إلى 3 مراحل: العزل، التفكيك، التحسين.



3.1. العزل والغلاف (Wrapper)

لا تلمس الداخل - غلف الدالة القديمة بواجهة جديدة:



// دالة قديمةfunction oldFormatDate(date) {    // ... 50 سطراً مع تحويرات    return formattedDate;}

// غلاف جديدfunction formatDateSafe(date) { if (!(date instanceof Date)) { throw new Error('تاريخ غير صالح'); } return oldFormatDate(date);}


3.2. التفكيك باستخدام Extract Function

استخرج الكتل المنطقية إلى دوال منفصلة:



// كان: دالة واحدة من 80 سطراًfunction handleOrder(order) {    // 1. التحقق    if (!order.id || !order.total) { ... }    // 2. حساب الخصم                

المدونات

توصيات الكتب