SOLID-Prinzipien

Wie du Verantwortungen und Abhängigkeiten so zuschneidest, dass Änderungen gezielt möglich bleiben

Fünf fundamentale Designprinzipien der objektorientierten Programmierung, die zu wartbarem, erweiterbarem und testbarem Code führen.

Fortgeschritten2 Min Lesezeit

Erklärung starten

Auf einen Blick

5 Punkte

  1. S – Single Responsibility: Jede Klasse hat genau eine Aufgabe
  2. O – Open/Closed: Offen für Erweiterung, geschlossen für Änderung
  3. L – Liskov Substitution: Unterklassen müssen die Oberklasse ersetzen können
  4. I – Interface Segregation: Kleine, spezifische Interfaces statt großer, allgemeiner
  5. D – Dependency Inversion: Abhängigkeiten auf Abstraktionen, nicht auf Implementierungen

Sofortantwort

SOLID-Prinzipien einfach erklärt

Fünf Prinzipien, die die Wartbarkeit und Erweiterbarkeit von Code fördern.

Kurz gesagt
S – Single Responsibility: Jede Klasse hat genau eine Aufgabe
Typischer Einsatz
Plugin-Architekturen, Testbarkeit, KI-Provider-Abstraktion
Wichtig zu wissen
D – Dependency Inversion: Abhängigkeiten auf Abstraktionen, nicht auf Implementierungen

SOLID-Prinzipien im Überblick

Die SOLID-Prinzipien sind fünf grundlegende Designprinzipien für objektorientierte Software, die wartbaren, erweiterbaren und testbaren Code fördern. Sie wurden von Robert C. Martin (Uncle Bob) formuliert und sind heute Standard in professioneller Softwareentwicklung. Für KI-Systeme sind SOLID-Prinzipien besonders relevant: ML-Pipelines, Inferenz-Services und Daten-Prozessoren werden schnell komplex – gute Architektur verhindert, dass sie unwartbar werden.

SOLID ist ein Akronym für fünf Prinzipien, die Robert C. Martin (Uncle Bob) populär gemacht hat. Sie helfen dabei, Software zu bauen, die sich leicht ändern und erweitern lässt.

Warum ist das wichtig?

Ohne gute Struktur wird Code schnell zum “Spaghetti-Code”: Alles hängt mit allem zusammen, eine kleine Änderung bricht zehn andere Stellen. SOLID verhindert das.

Die fünf Prinzipien auf einen Blick:

BuchstabePrinzipBedeutung
SSingle ResponsibilityJede Klasse macht nur eine Sache
OOpen/ClosedErweiterbar ohne bestehenden Code zu ändern
LLiskov SubstitutionUnterklassen müssen wie ihre Oberklasse funktionieren
IInterface SegregationKleine, spezifische Schnittstellen
DDependency InversionAbhängigkeiten über Abstraktionen, nicht konkrete Klassen

Praxis-Beispiel:

Stell dir vor, du baust einen KI-Chatbot. Ohne SOLID hättest du eine riesige Klasse, die API-Calls macht, Datenbank speichert, E-Mails sendet und Logs schreibt. Mit SOLID hast du kleine, austauschbare Bausteine – du kannst den LLM-Provider wechseln, ohne den Rest anzufassen.

Technisch betrachtet

S – Single Responsibility Principle

Eine Klasse sollte nur einen Grund haben, sich zu ändern.

// ❌ Schlecht: Klasse macht zu viel
class UserService {
  createUser() { ... }
  sendWelcomeEmail() { ... }
  generateReport() { ... }
}

// ✅ Gut: Getrennte Verantwortlichkeiten
class UserService { createUser() { ... } }
class EmailService { sendWelcomeEmail() { ... } }
class ReportService { generateReport() { ... } }

O – Open/Closed Principle

Offen für Erweiterung, geschlossen für Änderung.

// ✅ Neue Embedding-Provider hinzufügen ohne bestehenden Code zu ändern
interface EmbeddingProvider {
  embed(text: string): Promise<number[]>;
}

class OpenAIProvider implements EmbeddingProvider { ... }
class CohereProvider implements EmbeddingProvider { ... }
// Neuer Provider → neue Klasse, kein bestehender Code geändert

D – Dependency Inversion Principle

Abhängigkeiten auf Abstraktionen, nicht auf konkrete Implementierungen.

// ❌ Direkte Abhängigkeit
class RAGService {
  private db = new PineconeClient(); // fest verdrahtet
}

// ✅ Abstraktion
class RAGService {
  constructor(private vectorStore: VectorStore) {} // austauschbar
}

Schritt für Schritt

Wie SOLID-Prinzipien zu besseren Grenzen führen

  1. Änderungsgründe sichtbar machen

    Untersuche, welche fachlichen oder technischen Gründe einen Baustein verändern können. Wenn viele unabhängige Gründe in derselben Klasse oder Funktion liegen, entsteht eine schwer steuerbare Kopplung.

  2. Schnittstellen am Bedarf ausrichten

    Formuliere kleine Verträge für die tatsächlichen Nutzer einer Abhängigkeit. Eine Schnittstelle sollte nicht dazu zwingen, Funktionen zu kennen oder zu implementieren, die für die jeweilige Aufgabe nicht gebraucht werden.

  3. Implementierungen austauschbar halten

    Lasse Geschäftslogik von Abstraktionen abhängen, wenn mehrere Varianten, externe Dienste oder Tests dies sinnvoll machen. Die Abstraktion soll ein echtes Verhalten ausdrücken, nicht nur zusätzliche Schichten schaffen.

  4. Auswirkungen mit konkreten Änderungen prüfen

    Bewerte die Struktur anhand realer Änderungsfälle und Tests. Wenn eine Regel das Verständnis erschwert oder keine plausible Änderung erleichtert, ist sie kein Selbstzweck.

Konkretes Beispiel

Eine Benachrichtigung wird austauschbar

Ein System sendet Statusmeldungen direkt über einen einzelnen Anbieter. Für Tests und einen späteren Wechsel müssten viele Teile der Geschäftslogik geändert werden.

Direkte Kopplung

Fachliche Entscheidung, Formatierung und Kommunikation mit dem externen Dienst liegen in derselben Komponente. Fehler beim Anbieter sind schwer testbar und berühren unmittelbar den Kernablauf.

Klarer Vertrag

Die Geschäftslogik spricht einen kleinen Benachrichtigungs-Vertrag an. Konkrete Anbieter und Test-Doubles erfüllen diesen Vertrag, während Fehler und Ausfälle an einer kontrollierten Grenze behandelt werden.

Einordnung

Vorteile und Grenzen

Das spricht dafür

  • Macht Verantwortlichkeiten und Abhängigkeiten gezielt veränderbar und besser testbar.
  • Reduziert die Reichweite einzelner Änderungen in komplexen Softwareteilen.
  • Unterstützt klare Verträge zwischen Fachlogik, Infrastruktur und externen Diensten.

Das solltest du beachten

  • Zu frühe Abstraktion kann einfache Software unnötig kompliziert und indirekt machen.
  • Prinzipien lösen keine unklare Fachlichkeit oder fehlende Tests automatisch.
  • Eine gute Schnittstelle braucht Pflege, wenn sich reale Anforderungen verändern.
Vertiefung · für Fortgeschrittene

Verantwortung und Abhängigkeiten gestalten

Wissenskarte

Veränderbare Grenzen

Clean Code
Praktiken für verständlichen und wartbaren Quellcode.
Dependency Injection
Abhängigkeiten werden von außen übergeben statt intern erstellt – für bessere Testbarkeit.
Design Patterns
Bewährte Lösungen für häufige Probleme in der Softwareentwicklung.
Microservices
Anwendung besteht aus vielen kleinen, unabhängigen Services.
API
Schnittstelle zur Kommunikation zwischen Softwaresystemen.
SOLID-Prinzipien helfen, Software nach echten Änderungsgründen und klaren Verträgen aufzuteilen, ohne Abstraktion zum Selbstzweck zu machen. SOLID gliedert sich in: Clean Code, Dependency Injection, Design Patterns, Microservices, API.

01Einsatzbereiche

Wann ist SOLID-Prinzipien sinnvoll?

Geeignet für

  • Plugin-ArchitekturenOpen/Closed Principle für erweiterbare Systeme ohne bestehenden Code zu ändern
  • TestbarkeitDependency Inversion ermöglicht einfaches Mocken von Abhängigkeiten
  • KI-Provider-AbstraktionInterface Segregation für austauschbare LLM-Provider (OpenAI, Anthropic, lokale Modelle)
  • MicroservicesSingle Responsibility auf Service-Ebene: Jeder Service hat eine klare Domäne

↑ Inhalt

02Werkzeuge

Womit SOLID-Prinzipien umgesetzt wird

↑ Inhalt

Merksatz

SOLID ist wie die Bauvorschriften beim Hausbau

Man kann auch ohne sie bauen, aber mit ihnen steht das Haus stabiler, lässt sich leichter umbauen und hält länger.

  1. S – Single Responsibility: Jede Klasse hat genau eine Aufgabe
  2. O – Open/Closed: Offen für Erweiterung, geschlossen für Änderung
  3. L – Liskov Substitution: Unterklassen müssen die Oberklasse ersetzen können

04Redaktion

Herkunft und Stand

Redaktion und Aktualität

Ebenex RedaktionRedaktion

Veröffentlicht
Aktualisiert

Dieses Feld entwickelt sich schnell. Oben stehen Veröffentlichung und letzte Änderung; ein Prüfdatum kommt dazu, sobald die Erklärung nach ihrer letzten Änderung geprüft wurde.

↑ Inhalt

05FAQ

Häufige Fragen zu SOLID-Prinzipien

Muss man immer alle SOLID-Prinzipien befolgen?

Nein. SOLID sind Richtlinien, keine Gesetze. In kleinen Projekten kann striktes SOLID Over-Engineering sein. Die Prinzipien werden wichtiger, je größer und langlebiger ein Projekt ist.

Gelten SOLID-Prinzipien auch für funktionale Programmierung?

Die Konzepte dahinter (Trennung von Verantwortlichkeiten, Abstraktion, Erweiterbarkeit) gelten universell – die konkrete Umsetzung sieht in FP anders aus.

Wie kann ich die SOLID-Prinzipien in meinem Code umsetzen?

Um die SOLID-Prinzipien in deinem Code umzusetzen, solltest du sicherstellen, dass jede Klasse eine einzige Verantwortung hat und dass Abhängigkeiten über Schnittstellen verwaltet werden. Regelmäßige Code-Reviews und Refactoring helfen, die Prinzipien im Auge zu behalten und die Wartbarkeit zu erhöhen.

Gibt es Tools, die mir helfen können, die SOLID-Prinzipien zu überprüfen?

Ja, es gibt verschiedene Tools und Plugins, die dir helfen können, die Einhaltung der SOLID-Prinzipien zu überprüfen, wie z.B. statische Code-Analyse-Tools. Diese Tools analysieren deinen Code auf potenzielle Verstöße gegen die Prinzipien und geben dir Empfehlungen zur Verbesserung der Struktur und Wartbarkeit.

↑ Inhalt

06Weiterlernen

Was möchtest du als Nächstes verstehen?

  • Grundlage nachholen

    Microservices

    Anwendung besteht aus vielen kleinen, unabhängigen Services.

  • Technisch vertiefen

    Clean Code

    Praktiken für verständlichen und wartbaren Quellcode.

↑ Inhalt