إعادة هيكلة الكود القديم بلغة C#: من الألف إلى الياء
العمل مع الكود القديم (legacy) هو واقع لا مفر منه لأي مطور .NET. غالبًا ما تحتوي المشاريع القديمة بلغة C# على "كود سباغيتي" وأرقام سحرية وفئات ضخمة وغياب الاختبارات. بدلاً من إعادة كتابة كل شيء من الصفر (وهو مكلف ومحفوف بالمخاطر)، تسمح إعادة الهيكلة المدروسة بتحسين الكود تدريجيًا، مما يقلل الديون التقنية. في هذه المقالة، سنشرح استراتيجية خطوة بخطوة لإعادة هيكلة الكود القديم بلغة C# مع أمثلة محددة.
1. التحضير لإعادة الهيكلة: السلامة قبل كل شيء
القاعدة الأساسية لإعادة هيكلة الكود القديم هي عدم كسر ما يعمل. بدون اختبارات، أي تغيير قد يؤدي إلى أخطاء في بيئة الإنتاج. لذلك، المرحلة الأولى هي إنشاء "شبكة أمان".
1.1. إضافة الاختبارات (Characterization Tests)
إذا لم تكن هناك اختبارات، فيجب كتابتها. استخدم نهج Characterization Tests (اختبارات التوصيف). الفكرة: تقوم بتشغيل الكود الحالي بمدخلات مختلفة وتثبت السلوك الحالي كمرجع.
// مثال لطريقة قديمةpublic class LegacyCalculator{ public int CalculateTotal(int a, int b) { // كود قديم لا نفهمه تمامًا return a + b * 2; // منطق مشبوه }}
// اختبار توصيف[Test]public void CalculateTotal_WhenCalled_ReturnsCurrentBehavior(){ var calc = new LegacyCalculator(); int result = calc.CalculateTotal(3, 4); // نثبت النتيجة الحالية كمتوقعة Assert.AreEqual(11, result); // 3 + 4*2 = 11}بعد كتابة هذه الاختبارات، يمكنك إعادة الهيكلة بثقة، مع العلم أن الاختبارات ستكتشف أي تراجع.
1.2. عزل التبعيات
غالبًا ما يكون الكود القديم مرتبطًا بشدة بقاعدة البيانات أو نظام الملفات أو الخدمات الخارجية. استخدم Extract Interface وحقن التبعيات (DI) للعزل.
// كان: تبعية صلبةpublic class OrderProcessor{ private readonly SqlDatabase _db = new SqlDatabase(); public void Process(Order order) { _db.Save(order); }}
// أصبح: واجهة و DIpublic interface IOrderRepository{ void Save(Order order);}
public class OrderProcessor{ private readonly IOrderRepository _repository; public OrderProcessor(IOrderRepository repository) { _repository = repository; } public void Process(Order order) { _repository.Save(order); }}2. التقنيات الأساسية لإعادة هيكلة الكود القديم بلغة C#
بعد التحضير، يمكنك البدء في تحسين الكود. إليك التقنيات الرئيسية التي تعمل مع مشاريع .NET.
2.1. استخراج الطريقة (Extract Method)
الطرق الضخمة التي تحتوي على أكثر من 200 سطر هي من كلاسيكيات الكود القديم. قم بتقسيمها إلى طرق صغيرة قابلة للقراءة.
// قبل إعادة الهيكلةpublic void ProcessInvoice(Invoice invoice){ // 50 سطرًا لحساب الخصم decimal discount = 0; if (invoice.Total > 1000) discount = 0.1m; else if (invoice.Total > 500) discount = 0.05m; // ... الكثير من الكود // 30 سطرًا لإرسال البريد الإلكتروني // ... }
// بعد إعادة الهيكلةpublic void ProcessInvoice(Invoice invoice){ decimal discount = CalculateDiscount(invoice.Total); SendInvoiceEmail(invoice);}
private decimal CalculateDiscount(decimal total){ if (total > 1000) return 0.1m; if (total > 500) return 0.05m; return 0;}
private void SendInvoiceEmail(Invoice invoice){ // منطق الإرسال}2.2. استبدال الأرقام السحرية بالثوابت
الأرقام السحرية تجعل الكود غير مفهوم. استبدلها بالثوابت.
// سيءif (user.Role == 3) { /* admin */ }
// جيدpublic enum UserRole{ Guest = 1, User = 2, Admin = 3}
if (user.Role == (int)UserRole.Admin) { /* admin */ }