Zurück zum Blog
Clean Code März 2026 8 Min Lesezeit

Clean Code #4: SOLID — Die fünf Prinzipien guter Architektur

MN

Michael Nikolaus

Vorstand & Softwarearchitekt, Minicon eG

SOLID ist das Akronym für fünf Designprinzipien, die zu wartbarem, flexiblem und verständlichem Code führen. Jeder professionelle Entwickler sollte sie kennen — und anwenden können.

S — Single Responsibility Principle

Jede Klasse sollte genau einen Grund haben, sich zu ändern.

Eine UserService-Klasse, die gleichzeitig Benutzer anlegt, E-Mails versendet und Logs schreibt, hat drei Gründe sich zu ändern. Wenn sich das E-Mail-Format ändert, muss die UserService-Klasse angefasst werden — obwohl sich am User-Management nichts geändert hat.

// ❌ Drei Verantwortlichkeiten
class UserService {
    void CreateUser(User user) { /* ... */ }
    void SendWelcomeEmail(User user) { /* ... */ }
    void LogUserCreation(User user) { /* ... */ }
}

// ✅ Getrennte Verantwortlichkeiten
class UserService { void CreateUser(User user) { /* ... */ } }
class WelcomeMailer { void Send(User user) { /* ... */ } }
class AuditLogger { void LogCreation(User user) { /* ... */ } }

O — Open/Closed Principle

Software sollte offen für Erweiterung, aber geschlossen für Änderung sein.

Statt bestehenden Code zu ändern, wenn neue Anforderungen kommen, sollte die Architektur es erlauben, neue Funktionalität durch Erweiterung hinzuzufügen.

// ❌ Muss bei jedem neuen Typ geändert werden
decimal CalculateDiscount(string customerType) {
    if (customerType == "premium") return 0.2m;
    if (customerType == "business") return 0.15m;
    if (customerType == "student") return 0.1m;  // neu!
    return 0;
}

// ✅ Erweiterbar ohne Änderung
interface IDiscountStrategy { decimal Calculate(); }
class PremiumDiscount : IDiscountStrategy { ... }
class BusinessDiscount : IDiscountStrategy { ... }
class StudentDiscount : IDiscountStrategy { ... } // einfach hinzufügen

L — Liskov Substitution Principle

Subtypen müssen sich so verhalten, dass sie den Basistyp ersetzen können.

Das klassische Beispiel: Ein Square das von Rectangle erbt. Setzt man die Breite, muss beim Quadrat auch die Höhe geändert werden — das bricht die Erwartung, die man an ein Rechteck hat.

Wenn Ihr Code eine Basisklasse erwartet, muss jede Unterklasse funktionieren, ohne Überraschungen.

I — Interface Segregation Principle

Clients sollten nicht von Methoden abhängen, die sie nicht nutzen.

// ❌ Fettes Interface
interface IWorker {
    void Work();
    void Eat();
    void Sleep();
}

// ✅ Schlanke Interfaces
interface IWorkable { void Work(); }
interface IFeedable { void Eat(); }
// Ein Roboter implementiert nur IWorkable

D — Dependency Inversion Principle

High-Level-Module sollten nicht von Low-Level-Modulen abhängen. Beide sollten von Abstraktionen abhängen.

// ❌ Direkte Abhängigkeit
class OrderService {
    private SqlDatabase _db = new SqlDatabase(); // fest verdrahtet
}

// ✅ Abstraktion
class OrderService {
    private readonly IOrderRepository _repo;
    OrderService(IOrderRepository repo) => _repo = repo;
}

Das ermöglicht Testbarkeit (Mock-Repository), Flexibilität (anderer Datenspeicher) und klare Architekturschichten.

Fazit

SOLID ist kein Selbstzweck. Diese Prinzipien existieren, weil Software sich ändert. Code, der heute funktioniert, muss morgen erweitert, nächste Woche gefixt und nächstes Jahr vielleicht umgebaut werden. SOLID macht diese Änderungen sicher und beherrschbar.

Nächster Artikel: Clean Code #5: Kommentare — Wann sie helfen und wann sie schaden

Interesse geweckt?

Lassen Sie uns über Ihr Projekt sprechen

Das erste Gespräch ist kostenlos. Wir hören Ihnen zu und finden die beste Lösung für Sie.

Kontakt aufnehmen