إعادة هيكلة كود PHP: متى تحتاجها وكيف تتجنب الضرر
\n\nكل مطور PHP يواجه عاجلاً أم آجلاً كوداً يشعر برغبة في إعادة كتابته. مشاريع PHP القديمة مليئة بالأرقام السحرية (magic numbers)، ودوال تمتد لشاشات كاملة، وفئات تتحمل مسؤوليات كل شيء. تشعر برغبة في ترتيب الأمور. لكن هل يستحق الأمر؟ وإذا كان الأمر كذلك، كيف تجعل إعادة هيكلة كود PHP آمنة وفعالة؟
\n\nفي هذا المقال، سنشرح متى تكون إعادة الهيكلة ضرورية حقاً، ومتى يكون الأفضل ترك الأمور كما هي. سترى أمثلة حقيقية لكود سيء وجيد بلغة PHP، وستحصل على قائمة تحقق للإجراءات، وستفهم كيف لا تحول تحسين الكود إلى كارثة.
\n\nمتى تكون إعادة هيكلة كود PHP مبررة؟
\n\nإعادة الهيكلة هي تغيير البنية الداخلية للكود دون تغيير سلوكه الخارجي. يبدو الأمر بسيطاً، لكنه عملياً من أكثر المهام خطورة في التطوير. إليك العلامات التي تشير إلى أن الوقت قد حان للتفكير في تحسين كود PHP:
\n\n- \n
- رائحة الكود (code smells). دوال طويلة، تكرار، فئات شاملة (God objects)، أسماء متغيرات غير مفهومة. \n
- إضافة وظائف جديدة تصبح عذاباً. إذا كان كل طلب سحب (pull request) يكسر ثلاثة أماكن أخرى، فهذا جرس إنذار. \n
- لا تفهم ما تفعله الدالة بعد أسبوع من كتابتها. الكود السيء هو كود يحتاج إلى تعليقات لكل سطر. \n
- انتهاك مبدأ المسؤولية الواحدة (SRP). فئة UserManager التي تنشئ المستخدمين وترسل رسائل البريد الإلكتروني وتنشئ التقارير هي مرشح نموذجي لإعادة الهيكلة. \n
لكن هناك حالات قد تضر فيها إعادة هيكلة كود PHP:
\n- \n
- الموعد النهائي غداً والكود يعمل. \n
- لا توجد اختبارات. بدونها، أي تغيير هو لعبة روليت روسية. \n
- الكود مكتوب بشكل سريع لنموذج أولي سيتم التخلص منه غداً. \n
قواعد إعادة الهيكلة الآمنة
\n\nقبل أن تبدأ في إعادة هيكلة كود PHP، تذكر ثلاث قواعد حديدية:
\n\n- \n
- غطِّ الكود بالاختبارات. على الأقل اختبارات تكاملية. إذا لم تكن هناك اختبارات، فاكتبها للأجزاء الحرجة. \n
- أعد الهيكلة بخطوات صغيرة. دالة واحدة في كل مرة. ادفع التغيير، تحقق، ثم تابع. \n
- لا تخلط بين إعادة الهيكلة وإضافة الميزات. هاتان مهمتان مختلفتان. قم بهما في commits منفصلة. \n
أمثلة على إعادة هيكلة كود PHP: من السيء إلى الجيد
\n\nدعنا نلقي نظرة على أمثلة حقيقية. لنفترض أن لدينا دالة لحساب الخصم. إليك كيف تبدو في مشروع قديم نموذجي:
\n\nقبل إعادة الهيكلة (كود سيء)
\nfunction calculateDiscount($user, $order) {\n $discount = 0;\n if ($user->isVip()) {\n $discount = 10;\n if ($order->getTotal() > 1000) {\n $discount = 15;\n }\n }\n if (date('Y-m-d') == '2025-12-31') {\n $discount = $discount + 5;\n }\n if ($order->getItemsCount() > 5) {\n $discount = $discount + 3;\n }\n return $discount;\n}\n\nالمشاكل: تواريخ سحرية، أرقام ثابتة، خلط في المنطق (المستخدم، الطلب، التاريخ). إذا ظهر عرض جديد غداً، ستصبح الدالة أطول.
\n\nبعد إعادة هيكلة PHP (كود جيد)
\nclass DiscountCalculator {\n private const NEW_YEAR_DATE = '2025-12-31';\n \n public function calculate(User $user, Order $order): int {\n $discount = $this->getBaseDiscount($user) \n + $this->getHolidayBonus() \n + $this->getVolumeBonus($order);\n \n return min($discount, 50); // لا يزيد عن 50%\n }\n \n private function getBaseDiscount(User $user): int {\n if ($user->isVip() && $user->getTotalSpent() > 1000) {\n return 15;\n }\n return $user->isVip() ? 10 : 0;\n }\n \n private function getHolidayBonus(): int {\n retu