مبادئ SOLID في لغة C#: النظرية والتطبيق من الألف إلى الياء

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

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

ابدأ الدورة

مقدمة في مبادئ SOLID في لغة C#

\n

التطوير بلغة C# في بيئة .NET لا يتطلب فقط معرفة بناء الجملة، بل يتطلب أيضًا القدرة على تصميم أنظمة مرنة وقابلة للصيانة والاختبار. ولهذا الغرض تم إنشاء مبادئ SOLID — وهي خمس قواعد أساسية للبرمجة كائنية التوجه، صاغها روبرت مارتن (العم بوب).

\n

اختصار SOLID يعني:

\n
    \n
  • S — Single Responsibility Principle (مبدأ المسؤولية الواحدة)
  • \n
  • O — Open/Closed Principle (مبدأ الانفتاح/الإغلاق)
  • \n
  • L — Liskov Substitution Principle (مبدأ استبدال ليسكوف)
  • \n
  • I — Interface Segregation Principle (مبدأ فصل الواجهات)
  • \n
  • D — Dependency Inversion Principle (مبدأ عكس التبعيات)
  • \n
\n

في هذه المقالة، سنشرح كل مبدأ عمليًا مع أمثلة بلغة C#، ونوضح كيف يؤدي انتهاكها إلى مشاكل، وكيف أن التطبيق الصحيح يجعل الكود أنظف.

\n\n

1. مبدأ المسؤولية الواحدة (SRP)

\n

الجوهر: يجب أن يكون للفصل سبب واحد فقط للتغيير. بمعنى آخر، كل فصل مسؤول عن مهمة واحدة محددة بوضوح.

\n\n

انتهاك SRP في C#

\n

لنأخذ مثالًا نموذجيًا — فصل OrderService الذي يفعل الكثير:

\n
public class OrderService\n{\n    public void ProcessOrder(Order order)\n    {\n        // 1. الحفظ في قاعدة البيانات\n        SaveToDatabase(order);\n        \n        // 2. إرسال البريد الإلكتروني\n        SendEmail(order.CustomerEmail, "تم تأكيد الطلب");\n        \n        // 3. التسجيل\n        File.WriteAllText("log.txt", $"تم معالجة الطلب {order.Id}");\n    }\n    \n    private void SaveToDatabase(Order order) { /* ... */ }\n    private void SendEmail(string email, string message) { /* ... */ }\n}
\n

المشكلة: تغيير منطق إرسال البريد الإلكتروني أو طريقة التسجيل سيؤدي إلى تغيير فصل OrderService. هذا ينتهك SRP.

\n\n

التنفيذ الصحيح لـ SRP

\n

نقوم بتقسيم المسؤولية إلى خدمات منفصلة:

\n
public class OrderProcessor\n{\n    private readonly IOrderRepository _repository;\n    private readonly INotificationService _notificationService;\n    private readonly ILogger _logger;\n    \n    public OrderProcessor(\n        IOrderRepository repository,\n        INotificationService notificationService,\n        ILogger logger)\n    {\n        _repository = repository;\n        _notificationService = notificationService;\n        _logger = logger;\n    }\n    \n    public void ProcessOrder(Order order)\n    {\n        _repository.Save(order);\n        _notificationService.SendConfirmation(order.CustomerEmail);\n        _logger.Log($"تم معالجة الطلب {order.Id}");\n    }\n}\n\npublic interface IOrderRepository { void Save(Order order); }\npublic interface INotificationService { void SendConfirmation(string email); }\npublic interface ILogger { void Log(string message); }
\n

الآن كل فصل مسؤول فقط عن مهمته. تغيير منطق التسجيل لا يؤثر على معالجة الطلبات.

\n\n

2. مبدأ الانفتاح/الإغلاق (OCP)

\n

الجوهر: يجب أن تكون الفصول مفتوحة للتمديد ولكن مغلقة للتعديل. أي يجب أن تكون قادرًا على إضافة سلوك جديد دون تغيير الكود الموجود.

\n\n

انتهاك OCP في C#

\n

مثال كلاسيكي — آلة حاسبة مع شروط:

\n
public class AreaCalculator\n{\n    public double CalculateArea(object shape)\n    {\n        if (shape is Rectangle rect)\n            return rect.Width * rect.Height;\n        else if (shape is Circle circle)\n            return Math.PI * circle.Radius * circle.Radius;\n        // إضافة شكل جديد يتطلب تغيير هذه الطريقة!\n        throw new NotSupportedException();\n    }\n}                

المدونات

توصيات الكتب