أنماط التصميم في C++: تقنيات متقدمة وأمثلة

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

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

ابدأ الدورة

أنماط التصميم المتقدمة في C++: من النظرية إلى التطبيقات المعقدة

\n\n

أنماط التصميم هي حلول مثبتة للمشكلات النمطية التي تنشأ أثناء تطوير البرمجيات. إذا كانت الأنماط الأساسية (Singleton، Factory، Observer) مألوفة لكل مطور، فإن التقنيات المتقدمة تتطلب فهماً عميقاً للغة C++ وقوالبها وتعدد الوراثة والبرمجة الوصفية. في هذه المقالة، سنشرح أربعة أنماط قوية: Visitor وStrategy وState وCRTP مع أمثلة كود حقيقية وشرح متى يتم استخدامها.

\n\n

1. نمط Visitor (الزائر) — توسيع الوظائف دون تغيير الفئات

\n\n

يسمح نمط Visitor بإضافة عمليات جديدة إلى تسلسل هرمي للفئات دون تغيير الفئات نفسها. هذا مفيد بشكل خاص عندما يكون لديك هيكل كائنات ثابت ولكن خوارزميات معالجتها تتغير بشكل متكرر.

\n\n

مثال: معالجة الأشكال الهندسية

\n\n
#include <iostream>\n#include <vector>\n#include <memory>\n\n// تعريف مسبق\nclass Circle;\nclass Rectangle;\n\n// الزائر المجرد\nclass Visitor {\npublic:\n    virtual void visit(Circle& circle) = 0;\n    virtual void visit(Rectangle& rectangle) = 0;\n    virtual ~Visitor() = default;\n};\n\n// العنصر المجرد\nclass Shape {\npublic:\n    virtual void accept(Visitor& visitor) = 0;\n    virtual ~Shape() = default;\n};\n\n// العناصر الملموسة\nclass Circle : public Shape {\npublic:\n    double radius;\n    explicit Circle(double r) : radius(r) {}\n    void accept(Visitor& visitor) override {\n        visitor.visit(*this);\n    }\n};\n\nclass Rectangle : public Shape {\npublic:\n    double width, height;\n    Rectangle(double w, double h) : width(w), height(h) {}\n    void accept(Visitor& visitor) override {\n        visitor.visit(*this);\n    }\n};\n\n// الزائر الملموس — حساب المساحة\nclass AreaVisitor : public Visitor {\npublic:\n    double totalArea = 0.0;\n    void visit(Circle& circle) override {\n        totalArea += 3.14159 * circle.radius * circle.radius;\n    }\n    void visit(Rectangle& rectangle) override {\n        totalArea += rectangle.width * rectangle.height;\n    }\n};\n\nint main() {\n    std::vector<std::unique_ptr<Shape>> shapes;\n    shapes.push_back(std::make_unique<Circle>(5.0));\n    shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));\n\n    AreaVisitor areaCalc;\n    for (auto& shape : shapes) {\n        shape->accept(areaCalc);\n    }\n    std::cout << "Total area: " << areaCalc.totalArea << std::endl;\n    return 0;\n}\n
\n\n

متى تستخدم: عندما تحتاج إلى تنفيذ عمليات مختلفة على كائنات ذات تسلسل هرمي معقد دون تغيير كودها. العيب — إضافة نوع جديد يتطلب تغيير جميع الزوار.

\n\n

2. نمط Strategy (الاستراتيجية) — تغيير الخوارزميات بمرونة أثناء التشغيل

\n\n

يقوم Strategy بتغليف مجموعة من الخوارزميات القابلة للتبادل ويسمح باستبدالها أثناء التنفيذ. في C++، يتم تنفيذ ذلك غالباً عبر std::function أو الفئات الافتراضية.

\n\n

مثال: نظام فرز البيانات

\n\n
#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <memory>\n#include <functional>\n\n// السياق الذي يستخدم الاستراتيجية\nclass Sorter {\nprivate:\n    std::function<void(std::vector<int>&)> strategy_;\npublic:\n    explicit Sorter(std::function<void(std::vector<int>&)> strategy)\n        : strategy_(std::move(strategy)) {}\n\n    void setStrategy(std::function<void(std::vector<int>&)> newStrategy) {\n        strategy_ = std::move(newStrategy);\n    }\n\n    void sort(std::vector<int>& data) {\n        if (strategy_) {\n            strategy_(data);\n        }\n    }\n};\n\n// الاستراتيجيات الملموسة\nvoid bubbleSort(std::vector<int>& da                

المدونات

توصيات الكتب