Software Architecture

إعادة هيكلة الأنظمة الأحادية باستخدام مبدأ المسؤولية المفردة

تُعاني الأنظمة القديمة غالبًا من فئات متضخمة تتعامل مع اهتمامات كثيرة. يُصعّب نمط "الكائن الإلهي" هذا اختبار الكود وصيانته وتوسيعه. من خلال تطبيق مبدأ المسؤولية المفردة (SRP)، يمكننا تقسيم هذه الخدمات الأحادية إلى وحدات أصغر وأكثر تركيزًا دون إعادة كتابة النظام بأكمله. يوفر هذا الدليل خارطة طريق عملية لتنفيذ SRP في بيئات الإنتاج.

تحديد انتهاكات المسؤولية

الخطوة الأولى هي تحديد أماكن انتهاك SRP. تمتلك الفئة مسؤولية مفردة إذا كان هناك سبب واحد فقط لتغييرها. في الكود القديم، يتجلى هذا غالبًا كفئة تتعامل مع الوصول إلى قاعدة البيانات، ومنطق الأعمال، وتنسيق واجهة المستخدم في نفس الوقت.

ابحث عن هذه العلامات في قاعدة الكود الحالية لديك:

  • فئات ذات اعتماديات مفرطة على مكونات أخرى.
  • دوال تؤدي مهام متعددة غير ذات صلة (مثل التحقق من البيانات وإرسال رسائل البريد الإلكتروني).
  • تعقيد دائري عالٍ، مما يشير إلى منطق متشابك.
  • تعارضات دمج متكررة في ملفات محددة أثناء التطوير التعاوني.

الخطوة 1: استخراج منطق النطاق

أكثر طريقة آمنة لبدء إعادة الهيكلة هي استخراج منطق الأعمال النقي عن اهتمامات البنية التحتية. فكّر في فئة `OrderProcessor` قديمة تتعامل مع كل شيء بدءًا من حساب الإجماليات وحتى تحديث قاعدة البيانات.


// انتهاك قديم: الكائن الإلهي
public class OrderProcessor {
    public void processOrder(Order order) {
        // 1. منطق الأعمال
        double tax = order.getTotal() * 0.1;
        order.setTotal(order.getTotal() + tax);

        // 2. اهتمام بالبنية التحتية
        databaseConnection.update("orders", order);

        // 3. أثر جانبي
        emailService.sendConfirmation(order.getCustomerEmail());
    }
}

تتغير هذه الفئة لثلاثة أسباب: تغيير قواعد الضرائب، أو تغيير مخططات قاعدة البيانات، أو تغيير مزودي البريد الإلكتروني. لتطبيق SRP، نفصل منطق الحساب في خدمة مخصصة.

الخطوة 2: تطبيق نمط الاستراتيجية للتسعير

من خلال استخراج حساب الضريبة، ننشئ واجهة `TaxCalculator`. يعزل هذا المنطق ويسمح لنا بتبديل التنفيذات دون لمس تدفق الطلب الرئيسي.


// هيكل جديد متوافق مع SRP
public interface TaxCalculator {
    double calculate(Order order);
}

public class StandardTaxCalculator implements TaxCalculator {
    public double calculate(Order order) {
        return order.getTotal() * 0.1;
    }
}

// المعالج المُعاد هيكلته
public class OrderProcessor {
    private final TaxCalculator taxCalculator;
    private final OrderRepository repository;
    private final NotificationService notifier;

    public OrderProcessor(TaxCalculator taxCalculator, OrderRepository repo, NotificationService notifier) {
        this.taxCalculator = taxCalculator;
        this.repository = repo;
        this.notifier = notifier;
    }

    public void processOrder(Order order) {
        order.setTotal(order.getTotal() + taxCalculator.calculate(order));
        repository.save(order);
        notifier.sendConfirmation(order);
    }
}

الخطوة 3: فصل اهتمامات البنية التحتية

تالًي، نضمن أن يُفوّض منطق الاستمرارية والإشعار إلى الواجهات. يفصل هذا العملية التجارية الأساسية عن اختيارات التكنولوجيا المحددة. تعرف `OrderProcessor` الآن فقط على التجريدات، ملتزمةً بمبدأ عكس الاعتمادية، الذي يدعم SRP من خلال إبقاء الفئة مركزة حصريًا على تنسيق سير العمل.

عند اختبار هذا التنفيذ الجديد، يمكنك محاكاة `TaxCalculator` و `NotificationService` بسهولة. سابقًا، تطلب اختبار الوحدة للمعالج القديم `OrderProcessor` إعداد قاعدة بيانات وخادم بريد إلكتروني، مما يجعل الاختبارات بطيئة وغير مستقرة.

إدارة مرحلة الانتقال

إعادة هيكلة نظام أحادي كبير أمرٌ محفوف بالمخاطر. استخدم نمط "شجرة الخنق" (Strangler Fig) للتخفيف من هذا الخطر. أدخل المكونات الجديدة المتوافقة مع SRP خلف علم ميزة (feature flag). وجّه حركة المرور تدريجيًا إلى التنفيذ الجديد بينما لا يزال الكود القديم موجودًا. بمجرد ثقتك في استقرار الوحدات الجديدة، احذف الكود القديم.

الاختبارات الآلية غير قابلة للتفاوض خلال هذه العملية. قبل لمس أي كود قديم، اكتب اختبارات تكامل تغطي السلوك الحالي. تعمل هذه الاختبارات كشبكة أمان لك، مما يضمن أن تغييرات إعادة الهيكلة الخاصة بك تغيّر الهيكل ولكن ليس الوظيفة.

خاتمة

تطبيق مبدأ المسؤولية المفردة على الكود القديم لا يتعلق بإعادة كتابة كل شيء من الصفر؛ بل يتعلق بالتحسين التدريجي. من خلال عزل منطق الأعمال، وفصل اهتمامات البنية التحتية، واستخدام أنماط التصميم لإدارة الاعتماديات، يمكنك تحويل الأنظمة الأحادية الهشة إلى خدمات قابلة للصيانة. ابدأ صغيرًا، اختبر بدقة، والتزم بانضباط سبب واحد للتغيير لكل فئة. النتيجة هي كود أسهل في الفهم والاختبار والتوسيع لسنوات قادمة.

Share: