Entwurfsmuster in C++: Fortgeschrittene Techniken und Codebeispiele

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Fortgeschrittene Entwurfsmuster in C++: Von der Theorie zum echten Code



Entwurfsmuster sind bewährte Lösungen für typische Aufgaben in der objektorientierten Programmierung. Wenn Sie bereits die grundlegenden Muster (Singleton, Factory, Observer) beherrschen, ist es Zeit, zur nächsten Stufe überzugehen. In diesem Artikel analysieren wir vier fortgeschrittene Muster: Visitor, Strategy, State und Command. Alle Beispiele sind in modernem C++17/20 mit Smart Pointern, Polymorphismus und Templates geschrieben.



1. Visitor (Besucher)



Das Visitor-Muster ermöglicht das Hinzufügen neuer Operationen zu einer Klassenhierarchie, ohne die Klassen selbst zu ändern. Dies ist eine ideale Lösung für die Arbeit mit AST-Bäumen, grafischen Szenen oder Exportsystemen.



Problem

Sie haben eine Hierarchie geometrischer Formen (Circle, Rectangle, Triangle). Operationen müssen implementiert werden: Flächenberechnung, Zeichnung, Serialisierung in JSON. Wenn Sie Methoden zu jeder Klasse hinzufügen, wird das Open/Closed-Prinzip verletzt.



Lösung in 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); }};

// Konkreter Besucherclass 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 (Strategie)



Strategy ermöglicht es, den Algorithmus zur Datenverarbeitung zur Laufzeit zu ändern. Im Gegensatz zu Visitor, der mit einer Objekthierarchie arbeitet, kapselt Strategy einen einzelnen Algorithmus.



Reales Szenario

Ein Dateikomprimierungssystem. Der Benutzer wählt den Algorithmus: ZIP, GZIP oder einen eigenen. Anstelle einer if-else-Kette verwenden wir Strategy.



Implementierung mit 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)

Blogs

Buchempfehlungen