SOLID-Prinzipien in C++: Theorie und Praxis für sauberen Code

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

SOLID-Prinzipien in C++: Von der Theorie zur Praxis



SOLID ist ein Akronym für fünf grundlegende Prinzipien der objektorientierten Programmierung, formuliert von Robert C. Martin (Uncle Bob). Im Kontext von C++ helfen diese Prinzipien dabei, flexiblen, wartbaren und testbaren Code zu erstellen. In diesem Artikel analysieren wir jedes Prinzip mit praktischen Beispielen in C++.



1. Single Responsibility Principle (SRP) — Prinzip der einzigen Verantwortung



Kernaussage: Jede Klasse sollte nur einen Grund für eine Änderung haben. Einfach ausgedrückt – die Klasse übernimmt nur eine Aufgabe.



Schlechtes Beispiel (Verletzung des SRP):

class Report {public:    void generateReport() { /* Bericht generieren */ }    void saveToFile(const std::string& filename) { /* in Datei speichern */ }    void printReport() { /* Bericht drucken */ }};


Hier ist die Klasse Report für Generierung, Speicherung und Druck verantwortlich – drei verschiedene Verantwortlichkeiten.



Gutes Beispiel (Einhaltung des SRP):

class Report {public:    std::string generate() { /* Bericht generieren */ return "report data"; }};

class ReportSaver {public: void save(const std::string& data, const std::string& filename) { // in Datei speichern }};

class ReportPrinter {public: void print(const std::string& data) { // Bericht drucken }};


Jetzt hat jede Klasse eine klare Verantwortung, was das Testen und die Modifikation vereinfacht.



2. Open-Closed Principle (OCP) — Prinzip der Offenheit/Geschlossenheit



Kernaussage: Klassen sollten für Erweiterungen offen, aber für Modifikationen geschlossen sein. Sie sollten in der Lage sein, neue Funktionalität hinzuzufügen, ohne vorhandenen Code zu ändern.



Schlechtes Beispiel:

enum class ShapeType { Circle, Rectangle };

class Shape {public: ShapeType type;};

class AreaCalculator {public: double calculateArea(const Shape& shape) { if (shape.type == ShapeType::Circle) { // Berechnung der Kreisfläche return 3.14 * radius * radius; } else if (shape.type == ShapeType::Rectangle) { // Berechnung der Rechtecksfläche return width * height; } return 0.0; }};


Beim Hinzufügen einer neuen Form (z.B. Dreieck) müsste AreaCalculator geändert werden.



Gutes Beispiel (durch Polymorphie):

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(); }};


Jetzt reicht es aus, eine neue abgeleitete Klasse zu erstellen, um eine neue Form hinzuzufügen, ohne AreaCalculator zu ändern.



3. Liskov Substitution Principle (LSP) — Prinzip der Substitution von Barbara Liskov



Kernaussage: Objekte von Unterklassen sollten durch Objekte der Basisklasse ersetzbar sein, ohne die Korrektheit des Programms zu beeinträchtigen.



Klassische Verletzung (Rechteck-Quadrat):

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

Blogs

Buchempfehlungen