كودك يعمل - لكن هذا لا يعني أنه جيد
\n\nلقد كتبت سكريبت. يعمل. العملاء سعداء. لكن يمر شهر، وتنظر برعب إلى تلك الدالة نفسها التي نمت إلى 200 سطر. فيها خليط من استعلامات API، والتلاعب بـ DOM، وبعض السحر مع التواريخ. هل يبدو الأمر مألوفًا؟
\n\nمرحبًا بك في عالم حيث إعادة هيكلة كود JavaScript ليست نزوة من شخص يسعى للكمال، بل ضرورة حياتية. إذا كنت تريد أن يعيش مشروعك طويلاً ولا ينهار عند أول تعديل، فهذه المقالة لك.
\n\nما هي إعادة الهيكلة وما ليست كذلك
\n\nلنبدأ بالأهم. إعادة هيكلة كود JavaScript هي عملية تغيير البنية الداخلية للبرنامج دون تغيير سلوكه الخارجي. أنت لا تضيف وظائف جديدة، ولا تصلح أخطاء. أنت فقط تجعل الكود أنظف وأوضح وأسهل للصيانة.
\n\nكثيرون يخلطون بين إعادة الهيكلة وإعادة الكتابة. هما شيئان مختلفان. إعادة الكتابة هي عندما تتخلص من الكود القديم وتكتب جديدًا من الصفر. إعادة الهيكلة هي تطور، وليست ثورة. أنت تغير الكود بخطوات صغيرة، وتتحقق في كل مرة من أن شيئًا لم يتعطل.
\n\nمتى يجب إجراء إعادة هيكلة JavaScript؟
\n\nإليك بعض العلامات المؤكدة على أن كودك يصرخ طلبًا للمساعدة:
\n\n- \n
- قاعدة الثلاثة. إذا كنت تنسخ نفس قطعة الكود للمرة الثالثة - فقد حان وقت استخراجها في دالة منفصلة. \n
- دالة الوحش. دالة أطول من 30-40 سطرًا، يستحيل قراءتها بنظرة واحدة. \n
- "الأرقام السحرية". أرقام مبعثرة في الكود مثل
86400000أو42بدون تعليقات أو ثوابت. \n - المتغيرات العامة. إذا كنت تخشى تغيير متغير لأنك لا تعرف أين يُستخدم أيضًا. \n
- الاختبارات. إذا كنت تخشى إجراء تغييرات لعدم وجود اختبارات آلية - فهذا أول جرس إنذار. \n
لكن هناك حالات لا تحتاج فيها إعادة الهيكلة: قبل الموعد النهائي، في الإنتاج بدون اختبارات، أو عندما يكون الكود مكتوبًا على عجل لنموذج أولي سيتم التخلص منه غدًا.
\n\nتقنيات إعادة هيكلة JavaScript: من البسيط إلى المعقد
\n\n1. استخراج الدالة (Extract Function)
\n\nالتقنية الأكثر شيوعًا وأمانًا. تجد جزءًا من الكود يمكن تجميعه، وتستخرجه في دالة منفصلة.
\n\n// قبل إعادة الهيكلة\nfunction calculateInvoice(items) {\n let total = 0;\n for (let item of items) {\n total += item.price * item.quantity;\n }\n let discount = 0;\n if (total > 1000) {\n discount = total * 0.1;\n }\n return total - discount;\n}\n\n// بعد إعادة الهيكلة\nfunction calculateSubtotal(items) {\n return items.reduce((sum, item) => sum + item.price * item.quantity, 0);\n}\n\nfunction calculateDiscount(total) {\n return total > 1000 ? total * 0.1 : 0;\n}\n\nfunction calculateInvoice(items) {\n const subtotal = calculateSubtotal(items);\n const discount = calculateDiscount(subtotal);\n return subtotal - discount;\n}\n\n\nما الذي تغير؟ الآن كل دالة مسؤولة عن إجراء واحد. يمكنك إعادة استخدام calculateSubtotal في مكان آخر، ويمكن اختبار calculateDiscount بسهولة بشكل منفصل.
2. استبدال الأرقام السحرية بالثوابت
\n\nلا تستخدم أبدًا أرقامًا "عارية" في الكود. بعد شهر، لن تتذكر أنت نفسك ماذا يعني 86400000.
// سيء\nif (Date.now() - lastLogin > 86400000) {\n // طلب إعادة تسجيل الدخول\n}\n\n// جيد\nconst MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;\nconst ONE_DAY_MS = 86400000; // أو مجرد ثابت قابل للقراءة\n\nif (Date.now() - lastLogin > ONE_DAY_MS) {\n // طلب إعادة تسجيل الدخول\n}\n\n\n3. تبسيط الهياكل الشرطية
\n\nجمل if-else المتداخلة المعقدة هي العدو الرئيسي لقابلية القراءة. استخدم الإرجاع المبكر (early return) والعوامل الثلاثية.
<