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

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

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

ابدأ الدورة

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



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



1. نمط Visitor (الزائر)



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



المشكلة

لديك تسلسل هرمي للأشكال الهندسية (Circle, Rectangle, Triangle). تحتاج إلى تنفيذ عمليات: حساب المساحة، الرسم، التسلسل إلى JSON. إذا أضفت طرقًا إلى كل فئة، فسيتم انتهاك مبدأ الفتح/الإغلاق.



الحل بلغة C++17

#include <iostream>#include <memory>#include <vector>

// Forward declarationclass Circle;class Rectangle;

class Visitor {public: virtual void visit(Circle& c) = 0; virtual void visit(Rectangle& r) = 0; virtual ~Visitor() = default;};

class Shape {public: virtual void accept(Visitor& v) = 0; virtual ~Shape() = default;};

class Circle : public Shape {public: double radius = 5.0; void accept(Visitor& v) override { v.visit(*this); }};

class Rectangle : public Shape {public: double width = 4.0, height = 6.0; void accept(Visitor& v) override { v.visit(*this); }};

// زائر محددclass AreaVisitor : public Visitor {public: void visit(Circle& c) override { std::cout << "Circle area: " << 3.14159 * c.radius * c.radius << ""; } void visit(Rectangle& r) override { std::cout << "Rectangle area: " << r.width * r.height << ""; }};

int main() { std::vector<std::unique_ptr<Shape>> shapes; shapes.push_back(std::make_unique<Circle>()); shapes.push_back(std::make_unique<Rectangle>());

AreaVisitor av; for (auto& s : shapes) { s->accept(av); } return 0;}


2. نمط Strategy (الإستراتيجية)



يسمح Strategy بتغيير خوارزمية معالجة البيانات أثناء التنفيذ. على عكس Visitor الذي يعمل مع التسلسل الهرمي للكائنات، يقوم Strategy بتغليف خوارزمية منفصلة.



سيناريو واقعي

نظام ضغط الملفات. يختار المستخدم الخوارزمية: ZIP، GZIP أو خوارزمية مخصصة. بدلاً من سلسلة if-else نستخدم Strategy.



التنفيذ باستخدام std::function

#include <iostream>#include <functional>#include <string>

class CompressionContext {private: std::function<void(const std::string&)> strategy_;public: explicit CompressionContext(std::function<void(const std::string&)> strategy) : strategy_(std::move(strategy)) {}

void setStrategy(std::function<void(const std::string&)> strategy) { strategy_ = std::move(strategy); }

void compress(const std::string& data) { if (strategy_) { strategy_(data); } else { std::cout << "No strategy set"; } }};

int main() { auto zip = [](const std::string& d) { std::cout << "Compressing with ZIP: " << d << ""; }; auto gzip = [](const std::string& d) { std::cout << "Compressing with GZIP: " << d << ""; };

CompressionContext ctx(zip); ctx.compress("Hello World"); // ZIP

ctx.setStrategy(gzip)

المدونات

توصيات الكتب