Architekturmuster in C++: Wie man Code schreibt, den man zeigen kann

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

Warum C++ ohne Architektur eine Qual ist

\n

Wenn Sie jemals ein fremdes (oder Ihr eigenes altes) C++-Projekt geöffnet haben und das Gefühl hatten, dass Ihnen die Augen tränen, weil Tausende von Zeilen in einer einzigen Datei stehen und die Kompilierung zu einem Ritual mit einer Tasse Kaffee wird – Sie sind nicht allein. C++ bietet enorme Freiheit: Sie können Stile mischen, Operatoren überladen und Vorlagen-Magie betreiben. Aber Freiheit ohne Disziplin führt zu Chaos.

\n

Architekturmuster in C++ sind keine langweilige Theorie aus Universitätsvorlesungen. Es sind bewährte Rezepte, die ein Projekt retten, wenn es von einem "Spielzeug" zu einer industriellen Anwendung heranwächst. In diesem Artikel werden wir Architekturmuster in C++ besprechen, die das Leben wirklich einfacher machen: von MVC bis Observer. Und ja, es wird viel Code geben.

\n\n

Was ist ein Architekturmuster (und wie unterscheidet es sich von einem "einfachen Muster")

\n

Viele verwechseln C++-Entwurfsmuster (GoF: Singleton, Factory, Adapter) mit Architekturmustern. Der Unterschied ist einfach:

\n
    \n
  • Entwurfsmuster sind Mikro-Lösungen auf Klassen- oder Modulebene (z. B. wie man ein Objekt erstellt).
  • \n
  • Architekturmuster sind Makro-Lösungen auf der Ebene der gesamten Anwendung (wie Komponenten kommunizieren, wie Schichten getrennt sind).
  • \n
\n

Die Architektur bestimmt, ob Ihr Projekt in sechs Monaten zu einem "großen Schmutzkloß" (Big Ball of Mud) wird. Schauen wir uns daher die drei nützlichsten Muster für C++ an.

\n\n

1. MVC (Model-View-Controller) in C++: Teile und herrsche

\n

MVC ist ein Klassiker. Es teilt die Anwendung in drei Teile: Daten (Model), Darstellung (View) und Steuerungslogik (Controller). In C++ ist dies besonders relevant für GUI-Anwendungen (Qt, wxWidgets) oder sogar Konsolen-Dienstprogramme.

\n\n

Wie es im Code aussieht

\n

Stellen wir uns einen einfachen Taschenrechner vor. Das Model speichert das Ergebnis, die View zeigt es an, der Controller verarbeitet die Eingabe.

\n
#include <iostream>\n#include <string>\n\n// Model: weiß nichts über die GUI\nclass CalculatorModel {\npublic:\n    double add(double a, double b) {\n        result_ = a + b;\n        return result_;\n    }\n    double getResult() const { return result_; }\nprivate:\n    double result_ = 0;\n};\n\n// View: nur Darstellung\nclass CalculatorView {\npublic:\n    void showResult(double value) {\n        std::cout << "Ergebnis: " << value << std::endl;\n    }\n    void showError(const std::string& msg) {\n        std::cerr << "Fehler: " << msg << std::endl;\n    }\n};\n\n// Controller: verbindet Model und View\nclass CalculatorController {\npublic:\n    CalculatorController(CalculatorModel& model, CalculatorView& view)\n        : model_(model), view_(view) {}\n\n    void handleAdd(double a, double b) {\n        double res = model_.add(a, b);\n        view_.showResult(res);\n    }\nprivate:\n    CalculatorModel& model_;\n    CalculatorView& view_;\n};\n\nint main() {\n    CalculatorModel model;\n    CalculatorView view;\n    CalculatorController controller(model, view);\n\n    controller.handleAdd(5, 3); // Ausgabe: Ergebnis: 8\n    return 0;\n}
\n

Warum ist das cool? Sie können die Konsolen-View durch ein Qt-Widget ersetzen, ohne das Model anzufassen. Oder Sie können Unit-Tests für das Model hinzufügen, ohne die GUI zu starten. Dies ist die Grundlage für das Design von C++-Anwendungen von Grund auf.

\n\n

2. Observer (Beobachter): Wenn Änderungen für alle sichtbar sein sollen

\n

Stellen Sie sich vor: Sie haben einen Temperatursensor und mehrere Panels, die aktualisiert werden müssen, wenn sich die Temperatur ändert. Anstatt den Sensor jede Sekunde abzufragen (Polling), benachrichtigt der Observer selbst die Abonnenten. Dies ist ein Architekturmuster in C++, das den Code ereignisgesteuert macht.

\n\n

Implementierung in C++11 und neuer

\n

Wir verwenden intelligente Zeiger und std::function für Flexibilität.

\n
#include <iostream>\n#include <vector>\n#include <memory>\n#include <functional>\n\n// Schnittstelle des Beobachters\nclass IObserv                

Blogs

Buchempfehlungen