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

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

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

ابدأ الدورة

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



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



ما هو SOLID ولماذا هو ضروري؟

SOLID هو مجموعة من القواعد التي تساعد المطور على تجنب الكود "السيئ". يؤدي الالتزام بهذه المبادئ إلى تقليل الاقتران (coupling) وزيادة التماسك (cohesion) بين الوحدات. في لغة C++، حيث يمكن للإمكانيات القوية للقوالب (templates) والوراثة المتعددة أن تؤدي بسهولة إلى الفوضى، يعمل SOLID كبوصلة موثوقة. يتم فك تشفير كل حرف من الاختصار على النحو التالي:

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


مبدأ المسؤولية الواحدة (Single Responsibility)

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

التطبيق في C++: غالبًا ما يؤدي انتهاك هذا المبدأ إلى "كائنات إلهية" تفعل كل شيء في وقت واحد.

// ❌ سيء: الفصل ينتهك مبدأ SRPclass Report {public:    void generateReport() { /* توليد البيانات */ }    void saveToFile(const std::string& filename) { /* الكتابة إلى ملف */ }    void printReport() { /* الإرسال إلى الطابعة */ }};

// ✅ جيد: نقوم بتقسيم المسؤولياتclass ReportData {public: std::string generate() { return "بيانات التقرير"; }};

class ReportSaver {public: void save(const std::string& data, const std::string& filename) { std::ofstream file(filename); file << data; }};

class ReportPrinter {public: void print(const std::string& data) { /* طباعة */ }};

في المثال الجيد، كل فصل مسؤول عن مهمته الخاصة. هذا يبسط اختبار الكود وتعديله.



مبدأ الانفتاح/الإغلاق (Open-Closed)

النظرية: يجب أن تكون الكيانات البرمجية (الفصول، الوحدات، الدوال) مفتوحة للتمديد ولكن مغلقة للتعديل.

التطبيق في C++: يتم تحقيقه باستخدام التجريد وتعدد الأشكال.

// ❌ سيء: لإضافة شكل جديد، يجب تغيير الكودclass AreaCalculator {public:    double calculateArea(std::string shapeType, double param) {        if (shapeType == "circle") {            return 3.14 * param * param;        } else if (shapeType == "square") {            return param * param;        }        return 0.0;    }};

// ✅ جيد: نستخدم تعدد الأشكالclass Shape {public: virtual double area() const = 0; virtual ~Shape() = default;};

class Circle : public Shape { double radius;public: Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; }};

class Square : public Shape { double side;public: Square(double s) : side(s) {} double area() const override { return side * side; }};

class AreaCalculatorOCP {public: double calculate(const Shape& shape) { return shape.area(); }};

الآن لإضافة شكل جديد (مثل المثلث)، لا حاجة لتغيير A

المدونات

توصيات الكتب