إعادة هيكلة الكود القديم بلغة C#: دليل عملي لمطور .NET

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

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

ابدأ الدورة

إعادة هيكلة الكود القديم بلغة C#: كيفية تحويل مشروع قديم إلى منتج .NET حديث



كل مطور .NET يواجه عاجلاً أم آجلاً كوداً قديماً (legacy code) — فئات ضخمة تحتوي على 3000 سطر، منطق متشابك في ملفات .aspx.cs، وسلاسل سحرية (magic strings) منتشرة في جميع أنحاء المشروع. إعادة هيكلة (refactoring) هذا الكود ليست مجرد "تنظيف" للصياغة، بل هي مهمة استراتيجية: تحسين البنية دون كسر منطق الأعمال. في هذه المقالة، سنستعرض أساليب عملية لإعادة هيكلة كود C# ستساعدك على تحديث المشاريع الموروثة بأمان وفعالية.



1. التحضير: لماذا تتطلب إعادة هيكلة الكود القديم نهجاً خاصاً



الخطأ الأكبر للمبتدئين هو الاندفاع فوراً لإعادة كتابة الكود. في مشاريع C# .NET القديمة، غالباً ما تحتوي على تبعيات مخفية: فئات ثابتة (static classes)، حالات عامة (global states)، وارتباطات صلبة بقاعدة البيانات عبر ADO.NET. أي تغيير قد يتسبب في سلسلة من الأخطاء.



العلامات الرئيسية للكود القديم في C#:

  • غياب الاختبارات الوحدوية (Unit Tests) — الكود غير مغطى باختبارات الوحدة، مما يجعل إعادة الهيكلة محفوفة بالمخاطر.
  • الكائنات العملاقة (God Objects) — فئات تقوم بكل شيء: من العمل مع قاعدة البيانات إلى عرض واجهة المستخدم.
  • التبعيات الصلبة (Hard Dependencies) — إنشاء مثيلات مباشرة عبر new SqlConnection() داخل الدوال.
  • السلاسل والأرقام السحرية (Magic Strings and Numbers) — إعدادات مضمنة في الكود بدلاً من app.config أو appsettings.json.
  • استخدام واجهات برمجة تطبيقات قديمة — مثل WebClient بدلاً من HttpClient أو ArrayList بدلاً من List<T>.


قبل البدء في إعادة الهيكلة، تأكد من: تجميد متطلبات العميل، إعداد نظام التحكم في الإصدارات (Git)، وإنشاء "شبكة أمان" على شكل اختبارات تكاملية (integration tests).



2. إعادة هيكلة آمنة: استراتيجية "تحريك الجدار"



التقنية الكلاسيكية لـ C# هي نمط الخانق (Strangler Fig Pattern). بدلاً من إعادة كتابة كل شيء دفعة واحدة، تقوم باستبدال المكونات القديمة تدريجياً بمكونات جديدة، حتى يتوقف استخدام الكود القديم.



2.1. استخراج الواجهات (Interfaces) وحقن التبعيات (Dependency Injection)



أكثر الأنماط المضادة (anti-pattern) شيوعاً في C# القديم هي الدوال المساعدة الثابتة (static helper methods). لنلق نظرة على مثال:



// كود قديمpublic class OrderService{    public void ProcessOrder(int orderId)    {        var conn = new SqlConnection("Server=myServer;Database=myDB;...");        var cmd = new SqlCommand("SELECT * FROM Orders WHERE Id = " + orderId, conn);        // ... أطنان من المنطق    }}


الخطوة 1: استخراج واجهة للوصول إلى البيانات.



public interface IOrderRepository{    Order GetById(int orderId);}

public class OrderRepository : IOrderRepository{ private readonly string _connectionString;

public OrderRepository(string connectionString) { _connectionString = connectionString; }

public Order GetById(int orderId) { using var conn = new SqlConnection(_connectionString); // ... استعلام آمن }}


الخطوة 2: حقن التبعية عبر المُنشئ (constructor). الآن يمكنك استبدال المستودع (repository) في الاختبارات، وأصبح OrderService نفسه غير معتمد على تنفيذ محدد لقاعدة البيانات.



public class OrderService{    private readonly IOrderRepository _orderRepository;

public OrderService(IOrderRepository orderRepository) { _orderRepository = orderRepository; }

public void ProcessOrder(int orderId) { var order = _orderRepository.GetById(orderId); // ... منطق الأعمال }}


2.2. استبدال الأنواع القديمة بأنواع حديثة



في .NET Framework، كان يُستخدم غالباً ArrayList, Hashtable و

المدونات

توصيات الكتب