إعادة هيكلة الكود القديم بلغة C#: تقنيات وممارسات متقدمة

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

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

ابدأ الدورة

مقدمة: عندما يتحول الكود إلى كود قديم

كل مطور C# يعمل في شركة كبيرة، عاجلاً أم آجلاً، سيواجه مشاريع عمرها 5 أو 10 أو حتى 15 عامًا. يُسمى هذا الكود كودًا قديمًا (legacy). إنه يعمل ويحقق أرباحًا، لكن كل تغيير فيه يمثل مخاطرة. غياب الاختبارات، والارتباط الوثيق (tight coupling)، والفئات العملاقة بآلاف الأسطر، والسلاسل السحرية، والنسخ واللصق - هذا هو واقع الكود القديم.

إعادة الهيكلة البسيطة "بالعين" لن تنجح هنا. أنت بحاجة إلى استراتيجيات متقدمة تسمح لك بتحسين الكود تدريجيًا دون كسر منطق الأعمال. في هذه المقالة، سنناقش 4 طرق رئيسية لإعادة هيكلة الأنظمة القديمة بلغة C# (.NET) على مستوى متقدم.



1. استراتيجية "التين الخانق" (Strangler Fig): استبدال الوحدات دون إيقاف النظام

نمط Strangler Fig (التين الخانق) هو أسلوب كلاسيكي للاستبدال التدريجي للمكونات القديمة. الجوهر: لا تعيد كتابة النظام بأكمله مرة واحدة، بل تعترض تدريجيًا الاستدعاءات للوحدات القديمة وتوجهها إلى وحدات جديدة.



كيفية التنفيذ بلغة C#

أبسط طريقة هي استخدام الواجهات والمصانع. لنفترض أن لديك فئة قديمة OldOrderProcessor تُستخدم في جميع أنحاء المشروع.



// الواجهة القديمة (موجودة بالفعل)public interface IOrderProcessor{    void Process(Order order);}

// التنفيذ القديم (legacy)public class OldOrderProcessor : IOrderProcessor{ public void Process(Order order) { // كود يعمل منذ سنوات ولكنه غير نظيف }}


نقوم بإنشاء تنفيذ جديد ومصنع مع ميزة التبديل (feature toggle):



public class NewOrderProcessor : IOrderProcessor{    public void Process(Order order)    {        // كود جديد ونظيف    }}

public class OrderProcessorFactory{ public IOrderProcessor Create() { // مثال: التبديل بناءً على الإعدادات if (ConfigurationManager.AppSettings["UseNewProcessor"] == "true") return new NewOrderProcessor(); return new OldOrderProcessor(); }}


الآن يمكنك تفعيل المعالج الجديد لـ 5% من المستخدمين، ومراقبة الأخطاء، وزيادة النسبة تدريجيًا. عندما يصبح الكود القديم غير ضروري - احذفه.



2. عزل النواة: فصل الاهتمامات (Separation of Concerns) عبر حقن التبعية (Dependency Injection)

غالبًا ما يعاني الكود القديم من فئات الآلهة (God-classes) والاعتماد المباشر على قاعدة البيانات، ونظام الملفات، وواجهات API الخارجية. إدخال حقن التبعية (Dependency Injection - DI) هو الخطوة الأولى نحو النمطية.



مثال عملي

تخيل أن لديك فئة ReportGenerator التي تنشئ داخليًا SqlConnection:



public class ReportGenerator{    public void Generate()    {        using (var conn = new SqlConnection("..."))        {            // استعلامات        }    }}


هذا لا يمكن اختباره بدون قاعدة بيانات حقيقية. إعادة الهيكلة:



public interface IDataRepository{    IEnumerable<DataRow> GetReportData();}

public class ReportGenerator{ private readonly IDataRepository _repository;

public ReportGenerator(IDataRepository repository) { _repository = repository; }

public void Generate() { var data = _repository.GetReportData(); // إنشاء التقرير }}


الآن يمكنك استبدال المستودع بـ mock في اختبارات الوحدة. استخدم حاوية DI القياسية لـ .NET Core (Microsoft.Extensions.DependencyInjection) أو Autofac لحقن التبعيات.



3. اختبار الكود القديم: الاختبارات الذهبية (Golden Master) واختبارات التوصيف (Characterization Tests)

بدون اختبارات، إعادة الهيكلة هي قفزة بالمظلة بدون مظلة احتياطية. بالنسبة للكود القديم، فإن نهج اختبارات التوصيف (Characterization Tests) أو اختبارات النموذج الذهبي (Golden Master Testing) مثالي.



كيف يعمل هذا

تقوم بتشغيل

المدونات

توصيات الكتب