SOLID-Prinzipien in Go: Theorie und Praxis von A bis Z

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 Go: Theorie und Praxis von A bis Z

\n\n

SOLID ist ein Akronym für fünf grundlegende Prinzipien der objektorientierten Programmierung, die helfen, flexiblen, wartbaren und skalierbaren Code zu erstellen. Obwohl Go keine klassische OOP-Sprache ist (es gibt keine Klassen und Vererbung im traditionellen Sinne), sind diese Prinzipien anwendbar und äußerst nützlich bei der Entwicklung mit Go. In diesem Artikel werden wir jedes Prinzip anhand konkreter Beispiele erläutern, zeigen, wie man sie in Go anwendet, und erklären, warum dies wichtig ist.

\n\n

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

\n\n

Kernaussage: Jedes Modul, jede Klasse oder Funktion sollte nur einen Grund für eine Änderung haben. Mit anderen Worten: Eine Entität sollte für einen Teil der Funktionalität verantwortlich sein.

\n\n

In Go wird dies oft verletzt, wenn eine Struktur (struct) zu viele Aufgaben erledigt: mit der Datenbank arbeitet, E-Mails sendet, Berichte erstellt.

\n\n

Schlechtes Beispiel (Verletzung des SRP):

\n
type User struct {\n    Name  string\n    Email string\n}\n\nfunc (u *User) Save() error {\n    // Logik zum Speichern in der DB\n    return nil\n}\n\nfunc (u *User) SendWelcomeEmail() error {\n    // Logik zum Senden einer E-Mail\n    return nil\n}\n\nfunc (u *User) GenerateReport() string {\n    // Logik zur Berichtserstellung\n    return "report"\n}\n
\n\n

Gutes Beispiel (Einhaltung des SRP):

\n
type User struct {\n    Name  string\n    Email string\n}\n\ntype UserRepository struct{}\n\nfunc (r *UserRepository) Save(u *User) error {\n    // nur speichern\n    return nil\n}\n\ntype EmailService struct{}\n\nfunc (s *EmailService) SendWelcome(u *User) error {\n    // nur E-Mail senden\n    return nil\n}\n\ntype ReportGenerator struct{}\n\nfunc (g *ReportGenerator) Generate(u *User) string {\n    // nur Bericht generieren\n    return "report"\n}\n
\n\n

Fazit: Jede Struktur ist für ihre eigene Aufgabe verantwortlich. Eine Änderung der Speicherlogik wirkt sich nicht auf den E-Mail-Versand aus.

\n\n

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

\n\n

Kernaussage: Softwareentitäten (Klassen, Module, Funktionen) sollten für Erweiterungen offen, aber für Modifikationen geschlossen sein. Das heißt, Sie sollten in der Lage sein, neue Funktionalität hinzuzufügen, ohne vorhandenen Code zu ändern.

\n\n

In Go wird dies hervorragend über Interfaces umgesetzt.

\n\n

Schlechtes Beispiel (Verletzung des OCP):

\n
type PaymentProcessor struct{}\n\nfunc (p *PaymentProcessor) Process(paymentType string, amount float64) {\n    if paymentType == "credit_card" {\n        // Logik für Kreditkarte\n    } else if paymentType == "paypal" {\n        // Logik für PayPal\n    }\n    // Beim Hinzufügen eines neuen Typs müsste diese Methode geändert werden\n}\n
\n\n

Gutes Beispiel (Einhaltung des OCP):

\n
type PaymentMethod interface {\n    Pay(amount float64) error\n}\n\ntype CreditCard struct{}\n\nfunc (c *CreditCard) Pay(amount float64) error {\n    // Logik für Kreditkarte\n    return nil\n}\n\ntype PayPal struct{}\n\nfunc (p *PayPal) Pay(amount float64) error {\n    // Logik für PayPal\n    return nil\n}\n\nfunc ProcessPayment(method PaymentMethod, amount float64) error {\n    return method.Pay(amount)\n}\n
\n\n

Fazit: Um nun eine neue Zahlungsmethode (z. B. ApplePay) hinzuzufügen, reicht es aus, eine neue Struktur mit der Methode Pay() zu erstellen, ohne den vorhandenen Code zu ändern.

\n\n

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

\n\n

Kernaussage: Objekte in einem Programm sollten durch Instanzen ihrer Untertypen ersetzbar sein, ohne die Korrektheit des Programms zu beeinträchtigen. In Go bedeutet dies: Wenn eine Funktion ein Interface akzeptiert, muss jede Implementierung dieses Interfaces korrekt funktionieren, ohne Erwartungen zu verletzen.

\n\n

Schlechtes Beispiel (Verletzung des LSP):

\n
type Bird interface {\n    Fly() error\n}\n\nt                

Blogs

Buchempfehlungen