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

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

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

ابدأ الدورة

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



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



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



الجوهر: يجب أن يكون لكل class سبب واحد فقط للتغيير. بكلمات بسيطة — class يقوم بمهمة واحدة فقط.



مثال سيء (انتهاك SRP):

class Report {public:    void generateReport() { /* توليد التقرير */ }    void saveToFile(const std::string& filename) { /* الحفظ في ملف */ }    void printReport() { /* طباعة التقرير */ }};


هنا، class Report مسؤول عن التوليد، الحفظ، والطباعة — ثلاث مسؤوليات مختلفة.



مثال جيد (الالتزام بـ SRP):

class Report {public:    std::string generate() { /* توليد التقرير */ return "report data"; }};

class ReportSaver {public: void save(const std::string& data, const std::string& filename) { // الحفظ في ملف }};

class ReportPrinter {public: void print(const std::string& data) { // طباعة التقرير }};


الآن كل class لديه مسؤولية واحدة واضحة، مما يبسط عملية الاختبار والتعديل.



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



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



مثال سيء:

enum class ShapeType { Circle, Rectangle };

class Shape {public: ShapeType type;};

class AreaCalculator {public: double calculateArea(const Shape& shape) { if (shape.type == ShapeType::Circle) { // حساب مساحة الدائرة return 3.14 * radius * radius; } else if (shape.type == ShapeType::Rectangle) { // حساب مساحة المستطيل return width * height; } return 0.0; }};


عند إضافة شكل جديد (مثل المثلث)، سيتعين تعديل AreaCalculator.



مثال جيد (من خلال تعدد الأشكال):

class Shape {public:    virtual double area() const = 0;    virtual ~Shape() = default;};

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

class Rectangle : public Shape { double width, height;public: Rectangle(double w, double h) : width(w), height(h) {} double area() const override { return width * height; }};

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


الآن لإضافة شكل جديد، يكفي إنشاء class وراثي جديد دون لمس AreaCalculator.



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



الجوهر: يجب أن تكون كائنات الـ subclasses قابلة للاستبدال بكائنات الـ base class دون الإخلال بصحة البرنامج.



انتهاك كلاسيكي (مستطيل-مربع):

class Rectangle {protected:    int width, height;public:    void setWidth(int w) { width = w; }    void setHeight(int h) { height = h; }    int area() const { return width * height; }};

class Square : public Rectangle {public: void setWidth(int w) override { width = w; height

المدونات

توصيات الكتب