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

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

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

ابدأ الدورة

مقدمة: لماذا نحتاج مبادئ SOLID في لغة C#؟



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



في هذه المقالة، سنشرح كل مبدأ من مبادئ SOLID مع الأساس النظري والأمثلة العملية بلغة C#. ستتعلم كيفية تطبيقها في المشاريع الحقيقية، وتجنب الأخطاء الشائعة.



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



النظرية

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



التطبيق العملي بلغة C#

لننظر إلى مثال نموذجي لانتهاك مبدأ المسؤولية الواحدة - فصل يقوم في نفس الوقت بحساب الراتب وحفظ الموظف في قاعدة البيانات:



// ❌ انتهاك SRP: الفصل يقوم بأكثر من اللازمpublic class Employee{    public string Name { get; set; }    public decimal Salary { get; set; }

public decimal CalculateBonus() { return Salary * 0.1m; }

public void SaveToDatabase() { // منطق الحفظ في قاعدة البيانات Console.WriteLine("تم حفظ الموظف في قاعدة البيانات"); }}


لنصلح الموقف بتقسيم المسؤوليات:



// ✅ SRP: كل فصل مسؤول عن مهمته الخاصةpublic class Employee{    public string Name { get; set; }    public decimal Salary { get; set; }}

public class BonusCalculator{ public decimal Calculate(Employee employee) { return employee.Salary * 0.1m; }}

public class EmployeeRepository{ public void Save(Employee employee) { Console.WriteLine("تم حفظ الموظف في قاعدة البيانات"); }}


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



النظرية

يجب أن تكون الكيانات البرمجية (الفئات، الوحدات، الدوال) مفتوحة للتمديد ولكن مغلقة للتعديل. هذا يعني أنه يمكنك إضافة وظائف جديدة دون تغيير الكود الموجود.



التطبيق العملي بلغة C#

لنفترض أننا بحاجة لحساب مساحة أشكال مختلفة. انتهاك مبدأ OCP هو استخدام if-else أو switch لكل نوع جديد من الأشكال:



// ❌ انتهاك OCP: عند إضافة شكل جديد، يجب تغيير الكودpublic class AreaCalculator{    public double Calculate(object shape)    {        if (shape is Circle circle)            return Math.PI * circle.Radius * circle.Radius;        else if (shape is Rectangle rect)            return rect.Width * rect.Height;        // عند إضافة Triangle، سيتعين إضافة if آخر        return 0;    }}


الحل - استخدام التجريد وتعدد الأشكال:



// ✅ OCP: التمديد عبر الوراثة دون لمس الكود الموجودpublic abstract class Shape{    public abstract double GetArea();}

public class Circle : Shape{ public double Radius { get; set; } public override double GetArea() => Math.PI * Radius * Radius;}

public class Rectangle : Shape{ public double Width { get; set; } public double Height { get; set; } public override double GetArea() => Width * Height;}

public class AreaCalculator{ public double Calculate(Shape shape) { return shape.GetArea(); // يعمل مع أي شكل }}


3. مبدأ استبدال ليسكوف (LSP)



النظرية

يجب أن تكون كائنات الفئة الأساسية قابلة للاستبدال بكائنات فئاتها الفرعية دون إخلال

المدونات

توصيات الكتب