Welche Designmuster haben Sie in der Praxis verwendet?
sobes.tech KI
Antwort von AI
In der Praxis habe ich die folgenden Entwurfsmuster angewendet:
-
Fabrikmethode (Factory Method): Zum Erstellen von Objekten verschiedener Typen, ohne die konkrete Klasse anzugeben. Nützlich bei der Arbeit mit verschiedenen Datenquellen oder Konfigurationen.
// Beispiel für die Verwendung der Fabrikmethode class DataReader { read() { throw new Error("Methode nicht implementiert"); } } class FileReader extends DataReader { read() { console.log("Daten aus Datei lesen..."); } } class NetworkReader extends DataReader { read() { console.log("Daten aus Netzwerk lesen..."); } } class DataReaderFactory { createReader(type) { switch (type) { case "file": return new FileReader(); case "network": return new NetworkReader(); default: throw new Error("Unbekannter Lesertyp"); } } } const factory = new DataReaderFactory(); const fileReader = factory.createReader("file"); fileReader.read(); -
Singleton (Singleton): Um sicherzustellen, dass nur eine Instanz einer Klasse existiert und ein globaler Zugriffspunkt bereitgestellt wird. Wird häufig für Konfigurationsmanager oder Datenbankverbindungen verwendet.
// Beispiel für die Verwendung des Singleton class ConfigManager { constructor() { if (ConfigManager.instance) { return ConfigManager.instance; } this.config = {}; ConfigManager.instance = this; } setConfig(key, value) { this.config[key] = value; } getConfig(key) { return this.config[key]; } } const instance1 = new ConfigManager(); const instance2 = new ConfigManager(); console.log(instance1 === instance2); // true -
Beobachter (Observer): Zur Implementierung der "Eins-zu-viele"-Beziehung, bei der bei Änderung des Zustands eines Objekts (Sender) automatisch alle abhängigen Objekte (Abonnenten) benachrichtigt werden. Wird in Benachrichtigungssystemen, reaktiven Schnittstellen verwendet.
// Beispiel für die Verwendung des Beobachters class Observable { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(obs => obs !== observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { update(data) { console.log("Empfangene Aktualisierung:", data); } } const observable = new Observable(); const observer1 = new Observer(); const observer2 = new Observer(); observable.subscribe(observer1); observable.subscribe(observer2); observable.notify("Neue Daten verfügbar!"); -
Strategie (Strategy): Zur Definition einer Familie von Algorithmen, deren Kapselung und Austauschbarkeit. Ermöglicht es, den Algorithmus unabhängig von den Kunden, die ihn verwenden, zu ändern. Wird bei verschiedenen Varianten der Datenverarbeitung oder Ausführung von Operationen eingesetzt.
// Beispiel für die Verwendung der Strategie class PaymentStrategy { pay(amount) { throw new Error("Methode nicht implementiert"); } } class CreditCardPayment extends PaymentStrategy { pay(amount) { console.log(`Bezahlung von ${amount} mit Kreditkarte`); } } class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Bezahlung von ${amount} mit PayPal`); } } class PaymentContext { setStrategy(strategy) { this.strategy = strategy; } executePayment(amount) { this.strategy.pay(amount); } } const context = new PaymentContext(); context.setStrategy(new CreditCardPayment()); context.executePayment(100); context.setStrategy(new PayPalPayment()); context.executePayment(50); -
Dekorierer (Decorator): Zur dynamischen Hinzufügung neuer Funktionalität an ein Objekt, ohne seine Struktur zu ändern. Umhüllt das bestehende Objekt und bietet die gleiche Schnittstelle wie das umhüllte Objekt, aber mit zusätzlicher Funktionalität. Nützlich für Logging, Validierung, Caching.
// Beispiel für die Verwendung des Decorators class Component { operation() { return "Basis-Komponente"; } } class Decorator { constructor(component) { this.component = component; } operation() { return this.component.operation(); } } class ConcreteDecoratorA extends Decorator { operation() { return `ConcreteDecoratorA(${super.operation()})`; } } class ConcreteDecoratorB extends Decorator { operation() { return `ConcreteDecoratorB(${super.operation()})`; } } const simple = new Component(); console.log(simple.operation()); const decoratorA = new ConcreteDecoratorA(simple); console.log(decoratorA.operation()); const decoratorB = new ConcreteDecoratorB(decoratorA); console.log(decoratorB.operation()); -
Modul (Module): Obwohl das Modulsystem von Node.js eingebaut ist (CommonJS, ES Modules), wurde das Module pattern in JavaScript (vor dem Erscheinen nativer Module) verwendet, um private Mitglieder und eine öffentliche Schnittstelle zu erstellen. Es bildet die Grundlage für die Erstellung von gekapseltem Code.
Diese Muster haben mir geholfen, strukturierteren, skalierbareren und wartbareren Code zu schreiben.