SOLID-Prinzipien in JavaScript: Theorie und Praxis für Node.js

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 JavaScript: Von der Theorie zur Praxis mit Node.js

SOLID sind fünf fundamentale Prinzipien des objektorientierten Designs, formuliert von Robert C. Martin (Uncle Bob). Diese Prinzipien helfen dabei, flexiblen, wartbaren und skalierbaren Code zu erstellen. Obwohl viele SOLID mit klassischen OOP-Sprachen (Java, C#) verbinden, sind sie auch in JavaScript hervorragend anwendbar, besonders bei der Entwicklung mit Node.js. In diesem Artikel analysieren wir jedes Prinzip anhand konkreter Beispiele.



Single Responsibility Principle (SRP)

SRP besagt: „Eine Klasse (oder ein Modul) sollte nur einen einzigen Grund für eine Änderung haben“. Das bedeutet, dass jedes Modul für eine spezifische Aufgabe verantwortlich ist.



Schlechtes Beispiel (Verletzung des SRP):

class UserService {    createUser(data) { /* Logik zur Erstellung */ }    sendWelcomeEmail(email) { /* E-Mail-Versand */ }    logActivity(action) { /* Logging */ }}

Hier ist eine Klasse für die Benutzerverwaltung, den E-Mail-Versand und das Logging verantwortlich. Wenn sich das Log-Format ändert, müsste UserService geändert werden – obwohl sich seine Hauptaufgabe nicht geändert hat.



Gutes Beispiel (Einhaltung des SRP):

class UserRepository {    createUser(data) { /* nur Datenbankarbeit */ }}

class EmailService { sendWelcomeEmail(email) { /* nur Versand */ }}

class Logger { logActivity(action) { /* nur Logging */ }}

class UserService { constructor(userRepo, emailService, logger) { this.userRepo = userRepo; this.emailService = emailService; this.logger = logger; } createUser(data) { const user = this.userRepo.createUser(data); this.emailService.sendWelcomeEmail(user.email); this.logger.logActivity('User created'); return user; }}

Jetzt ist jede Klasse für ihren eigenen Verantwortungsbereich zuständig. Durch die Kombination in UserService erhalten wir Flexibilität und isolierte Änderungen.



Open/Closed Principle (OCP)

OCP besagt: „Softwareentitäten sollten offen für Erweiterung, aber geschlossen für Modifikation sein“. Das bedeutet, wir sollten in der Lage sein, neue Funktionalität hinzuzufügen, ohne vorhandenen Code zu ändern.



Schlechtes Beispiel (Verletzung des OCP):

class PaymentProcessor {    processPayment(type, amount) {        if (type === 'card') { /* Kartenverarbeitung */ }        else if (type === 'paypal') { /* PayPal-Verarbeitung */ }        // Beim Hinzufügen eines neuen Typs muss diese Methode geändert werden    }}


Gutes Beispiel (Einhaltung des OCP):

class PaymentStrategy {    pay(amount) { throw new Error('Must be implemented'); }}

class CardPayment extends PaymentStrategy { pay(amount) { console.log(`Paid ${amount} via Card`); }}

class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Paid ${amount} via PayPal`); }}

class PaymentProcessor { constructor(strategy) { this.strategy = strategy; } processPayment(amount) { this.strategy.pay(amount); }}

// Verwendungconst cardPayment = new PaymentProcessor(new CardPayment());cardPayment.processPayment(100);

const paypalPayment = new PaymentProcessor(new PayPalPayment());paypalPayment.processPayment(200);

Um eine neue Zahlungsmethode hinzuzufügen, muss jetzt nur eine neue Klasse erstellt werden, die von PaymentStrategy erbt, und diese an PaymentProcessor übergeben werden. Der ursprüngliche Code wird nicht geändert.



Liskov Substitution Principle (LSP)

LSP besagt: „Objekte in einem Programm sollten durch Instanzen ihrer Subtypen ersetzbar sein, ohne die Korrektheit des Programms zu beeinträchtigen“. Mit anderen Worten: Wenn Sie eine Basisklasse haben, sollten Sie deren Instanzen durch Instanzen einer abgeleiteten Klasse ersetzen können, ohne dass das Programm fehlerhaft wird.

Blogs

Buchempfehlungen