إعادة هيكلة الكود القديم بلغة Kotlin: دليل خطوة بخطوة

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

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

ابدأ الدورة
```html

إعادة هيكلة الكود القديم (Legacy) في Kotlin: استراتيجية وأمثلة عملية



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



1. التحضير والاختبار: أساس الأمان



قبل تغيير الكود، من الضروري ضمان عمله بشكل صحيح بعد التعديلات. بدون اختبارات، تتحول إعادة الهيكلة إلى تخمين.



  • اكتب اختبارات التوصيف (Characterization Tests): قم بتشغيل الكود الحالي بمدخلات مختلفة وسجل القيم الناتجة. هذه الاختبارات ستصبح "شبكة الأمان" الخاصة بك.
  • استخدم التعليمة @Deprecated: إذا لم تتمكن من حذف واجهة برمجة التطبيقات (API) العامة القديمة فورًا، قم بتمييزها كـ @Deprecated مع ذكر البديل.
  • اعمل بخطوات صغيرة: لا تقم أبدًا بإعادة هيكلة أكثر من كتلة منطقية واحدة في كل مرة. يجب أن يجتاز كل commit جميع الاختبارات.


مثال على اختبار توصيف لدالة قديمة:



// كود قديمfun calculateTotal(items: List<Int>?): Int {    if (items == null) return 0    var sum = 0    for (item in items) {        sum += item    }    return sum}

// اختبار@Testfun `calculateTotal returns sum or zero`() { assertEquals(0, calculateTotal(null)) assertEquals(6, calculateTotal(listOf(1, 2, 3))) assertEquals(0, calculateTotal(emptyList()))}


2. التخلص من عدم الأمان (null-safety) واستخدام دوال النطاق (Scope-functions)



غالبًا ما يعاني الكود القديم من الفحوصات الزائدة عن العدم (null). توفر Kotlin أدوات أنيقة للعمل مع الأنواع القابلة للعدم (nullable).



ما نقوم به: استبدال الجمل المتداخلة if (x != null) بـ let أو run أو also.



// قبل إعادة الهيكلةfun processUser(user: User?) {    if (user != null) {        if (user.name != null) {            println("User: ${user.name}")        }    }}

// بعد إعادة الهيكلةfun processUser(user: User?) { user?.let { u -> u.name?.let { name -> println("User: $name") } }}

// أو بشكل أقصر باستخدام runfun processUserShort(user: User?) { user?.run { name?.let { println("User: $it") } }}


هذا الأسلوب يجعل الكود أكثر تصريحية (declarative) ويقلل من احتمالية تفويت الفحص.



3. استبدال الفئات المساعدة (Utility classes) بدوال الإضافة (Extension-functions)



في مشاريع Java القديمة، غالبًا ما توجد فئات مساعدة ثابتة (مثل StringUtils, DateUtils). في Kotlin، من الأفضل استبدالها بدوال الإضافة (extension functions).



لماذا هذا مهم: دوال الإضافة تجعل الكود أكثر قابلية للقراءة وتسمح لبيئة التطوير (IDE) باقتراحها كطرق خاصة بالفئة نفسها.



// أسلوب Java القديمobject StringUtils {    fun isPalindrome(input: String): Boolean {        val cleaned = input.filter { it.isLetterOrDigit() }.lowercase()        return cleaned == cleaned.reversed()    }}

// الاستخدامval result = StringUtils.isPalindrome("A man, a plan, a canal: Panama")

// إعادة الهيكلة في Kotlinfun String.isPalindrome(): Boolean { val cleaned = this.filter { it.isLetterOrDigit() }.lowercase() return cleaned == cleaned.reversed()}

// الاستخدامval result = "A man, a plan, a canal: Panama".isPalindrome()


يجدر أيضًا الانتباه إلى استبدال java.util.Date بـ java.time (LocalDate, Instant) — فهذا سيزيد من أمان العمل مع الوقت.



4. تحسين

```

المدونات

توصيات الكتب