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

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

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

ابدأ الدورة

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

\n

كل مطور واجه كوداً قديماً (Legacy) - ذلك "الصندوق الأسود" الذي تخشى لمسه لأن "هو شغال، ومش لازم نتدخل". لكن، عندما تبدأ قاعدة الكود بلغة Kotlin (أو Java التي يتم ترحيلها تدريجياً) في إبطاء التطوير، وتراكم الأخطاء، وإخافة أعضاء الفريق الجدد، يحين وقت إعادة الهيكلة. إعادة هيكلة الكود القديم (Legacy) بلغة Kotlin ليست مجرد إعادة كتابة، بل هي عملية منهجية لتحسين البنية الداخلية دون تغيير السلوك الخارجي.

\n

في هذه المقالة، سنستعرض المسار الكامل: من تحليل الحالة الحالية إلى تطبيق الممارسات الحديثة في Kotlin. ستتعلم كيفية تحويل الكود القديم بأمان باستخدام إمكانيات اللغة (العدميّة (Nullability)، دوال الإضافة (Extension Functions)، الفئات المختومة (Sealed Classes)) دون كسر بيئة الإنتاج (Production).

\n\n

1. التشخيص: كيفية تقييم حجم الكود القديم (Legacy)

\n

قبل البدء في إعادة الهيكلة، يجب أن تفهم ما تتعامل معه. غالباً ما يأتي الكود القديم (Legacy) بلغة Kotlin من مشاريع بدأت بالكتابة بلغة Java ثم تم ترحيلها جزئياً. العلامات النموذجية:

\n
    \n
  • الكائنات العملاقة (God Objects) - فئات تفعل كل شيء: من التحليل (Parsing) إلى منطق الأعمال (Business Logic).
  • \n
  • غياب الاختبارات - الكود غير مغطى باختبارات الوحدة (Unit Tests)، وأي تغيير محفوف بالمخاطر.
  • \n
  • البيانات القابلة للتغيير (Mutable Data) - وفرة من var بدلاً من val، وقوائم قابلة للتغيير (Mutable Lists) يتم تمريرها بين الوحدات.
  • \n
  • كابوس العدم (Null Nightmare) - عامل !! منتشر في جميع أنحاء الكود، وتحققّات لا نهائية if (x != null).
  • \n
\n

للتشخيص، استخدم الأدوات: Detekt (التحليل الثابت لـ Kotlin)، SonarQube (مقاييس الجودة)، و IntelliJ IDEA Inspections. أنشئ قائمة مراجعة للنقاط الإشكالية وحدد أولوياتها حسب المخاطر وتكرار الاستخدام.

\n\n

1.1. رسم خريطة التبعيات

\n

خذ ورقة أو استخدم PlantUML لتصور العلاقات بين الفئات. إذا كان رسم التبعيات يشبه شبكة العنكبوت - فهذا جرس إنذار. انتبه بشكل خاص للتبعيات الدائرية: فهي تجعل الكود هشاً وصعب الاختبار.

\n\n

2. استراتيجية إعادة الهيكلة: خطة عمل خطوة بخطوة

\n

إعادة الهيكلة بدون خطة هي طريق نحو الكارثة. استخدم نهج "تقنية الخطوات الصغيرة" (Baby Steps). خوارزمية العمل:

\n
    \n
  1. وثّق السلوك - اكتب اختبارات التوصيف (Characterization Tests) التي تثبت السلوك الحالي للنظام.
  2. \n
  3. اعزل التغييرات - اعمل في فرع منفصل، واستخدم مفاتيح الميزات (Feature Toggles) للأجزاء المعقدة.
  4. \n
  5. إعادة الهيكلة وفق الأنماط - طبق تقنيات مجربة (Extract Method، Replace Conditional with Polymorphism، Introduce Parameter Object).
  6. \n
  7. الترحيل التدريجي - لا تحاول إعادة كتابة كل شيء دفعة واحدة. استخدم تعليقات @Deprecated للطرق القديمة.
  8. \n
\n\n

2.1. مثال: استبدال if-else بـ when والفئات المختومة (Sealed Classes)

\n

الكود القديم (Legacy) النموذجي بلغة Kotlin يحتوي على سلاسل if-else لمعالجة الحالات:

\n
// سيء: علامة قابلة للتغيير و if-else\nvar status = "active"\nif (status == "active") {\n    // ...\n} else if (status == "inactive") {\n    // ...\n} else {\n    throw Exception("Unknown status")\n}
\n

إعادة الهيكلة باستخدام الفئات المختومة (Sealed Classes):

\n
// جيد: نموذج آمن من حيث النوع\nsealed class Status {\n    object Active : Status()\n    object Inactive : Status()\n    data class Custom(val reason: String) : Status()\n}\n\nfun handleStatus(status: Status) = when (status) {\n    is Status.Active -> // معالجة\n    is Status.Inactive -> // معالجة\n    is Status.Custom -> // معالجة مع reason\n}
\n

هذا يلغي الحاجة إلى else ويجعل الكود قابلاً للتوسع.

\n\n

3. العمل الآمن مع القيم القابلة للعدم (Nullable) والمجموعات (Collections)

\n

الكود القديم (Legacy) غالباً

المدونات

توصيات الكتب