Welke ontwerppatronen heb je in de praktijk gebruikt?
sobes.tech AI
Antwoord van AI
In de praktijk heb ik de volgende ontwerppatronen toegepast:
-
Factory Method (Fabriekmethode): Voor het maken van objecten van verschillende types zonder de specifieke klasse aan te geven. Handig bij het werken met verschillende gegevensbronnen of configuraties.
// Voorbeeld van het gebruik van de fabriekmethode class DataReader { read() { throw new Error("Method not implemented"); } } class FileReader extends DataReader { read() { console.log("Gegevens lezen uit bestand..."); } } class NetworkReader extends DataReader { read() { console.log("Gegevens lezen uit netwerk..."); } } class DataReaderFactory { createReader(type) { switch (type) { case "file": return new FileReader(); case "network": return new NetworkReader(); default: throw new Error("Onbekend lezer type"); } } } const factory = new DataReaderFactory(); const fileReader = factory.createReader("file"); fileReader.read(); -
Singleton (Enkelvoudig): Zorgt dat er slechts één instantie van een klasse bestaat en biedt een globale toegang tot die instantie. Vaak gebruikt voor configuratiebeheerders of databaseverbindingen.
// Voorbeeld van het gebruik van een 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 -
Observer (Waarnemer): Voor het implementeren van een "een-op-velen" relatie, waarbij alle afhankelijke objecten (abonnees) automatisch worden geïnformeerd wanneer de toestand van één object (uitgever) verandert. Gebruikt in notificatiesystemen, reactieve interfaces.
// Voorbeeld van het gebruik van een observer 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("Ontvangen update:", data); } } const observable = new Observable(); const observer1 = new Observer(); const observer2 = new Observer(); observable.subscribe(observer1); observable.subscribe(observer2); observable.notify("Nieuwe gegevens beschikbaar!"); -
Strategie (Strategy): Voor het definiëren van een familie algoritmen, het inkapselen ervan en het uitwisselbaar maken. Maakt het mogelijk om het algoritme onafhankelijk van de clients te veranderen. Gebruikt voor verschillende gegevensverwerkings- of operationele varianten.
// Voorbeeld van het gebruik van strategie class PaymentStrategy { pay(amount) { throw new Error("Method not implemented"); } } class CreditCardPayment extends PaymentStrategy { pay(amount) { console.log(`Betaling van ${amount} met creditcard`); } } class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Betaling van ${amount} via 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); -
Decorator (Decorator): Voor het dynamisch toevoegen van nieuwe functionaliteit aan een object zonder de structuur te wijzigen. Omhult het bestaande object, biedt dezelfde interface als het omhulde object, maar met toegevoegde functionaliteit. Handig voor logging, validatie, caching.
// Voorbeeld van het gebruik van een decorator class Component { operation() { return "Basiscomponent"; } } 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()); -
Module (Module): Hoewel het modulesysteem in Node.js ingebouwd is (CommonJS, ES Modules), werd het Module pattern in JavaScript (voor het verschijnen van native modules) gebruikt om private leden en een publieke interface te creëren. Dit vormt de basis voor het bouwen van ingekapselde code.
Deze patronen hielpen mij om meer gestructureerde, schaalbare en onderhoudbare code te maken.