Quels modèles de conception avez-vous utilisés en pratique?
sobes.tech IA
Réponse de l'IA
En pratique, j'ai appliqué les patrons de conception suivants:
-
Méthode de Fabrique (Factory Method): Pour créer des objets de différents types sans spécifier la classe concrète de création. Utile lors de la gestion de différentes sources de données ou configurations.
// Exemple d'utilisation de la méthode de fabrique class DataReader { read() { throw new Error("Méthode non implémentée"); } } class FileReader extends DataReader { read() { console.log("Lecture des données depuis le fichier..."); } } class NetworkReader extends DataReader { read() { console.log("Lecture des données depuis le réseau..."); } } class DataReaderFactory { createReader(type) { switch (type) { case "file": return new FileReader(); case "network": return new NetworkReader(); default: throw new Error("Type de lecteur inconnu"); } } } const factory = new DataReaderFactory(); const fileReader = factory.createReader("file"); fileReader.read(); -
Singleton (Singleton): Pour garantir qu'une seule instance d'une classe existe et fournir un point d'accès global. Souvent utilisé pour les gestionnaires de configuration ou les connexions à la base de données.
// Exemple d'utilisation du 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 -
Observateur (Observer): Pour implémenter la relation "un à plusieurs", où la modification de l'état d'un objet (émetteur) entraîne automatiquement la notification de tous les objets dépendants (abonnés). Utilisé dans les systèmes de notification, interfaces réactives.
// Exemple d'utilisation de l'observateur 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("Mise à jour reçue:", data); } } const observable = new Observable(); const observer1 = new Observer(); const observer2 = new Observer(); observable.subscribe(observer1); observable.subscribe(observer2); observable.notify("Nouvelles données disponibles!"); -
Stratégie (Strategy): Pour définir une famille d'algorithmes, les encapsuler et les rendre interchangeables. Permet à l'algorithme de changer indépendamment des clients qui l'utilisent. Utilisé pour différentes variantes de traitement de données ou d'exécution d'opérations.
// Exemple d'utilisation de la stratégie class PaymentStrategy { pay(amount) { throw new Error("Méthode non implémentée"); } } class CreditCardPayment extends PaymentStrategy { pay(amount) { console.log(`Paiement de ${amount} avec une carte de crédit`); } } class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Paiement de ${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); -
Décorateur (Decorator): Pour ajouter dynamiquement une nouvelle fonctionnalité à un objet sans changer sa structure. Enveloppe l'objet existant, fournissant la même interface que l'objet enveloppé, mais avec une fonctionnalité supplémentaire. Utile pour la journalisation, la validation, la mise en cache.
// Exemple d'utilisation du décorateur class Component { operation() { return "Composant de base"; } } class Decorator { constructor(component) { this.component = component; } operation() { return this.component.operation(); } } class ConcreteDecoratorA extends Decorator { operation() { return `DécorateurConcretA(${super.operation()})`; } } class ConcreteDecoratorB extends Decorator { operation() { return `DécorateurConcretB(${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): Bien que le système de modules de Node.js soit intégré (CommonJS, ES Modules), le patron Module pattern en JavaScript (avant l'apparition des modules natifs) était utilisé pour créer des membres privés et une interface publique. C'est la base pour construire un code encapsulé.
Ces patrons m'ont aidé à créer un code plus structuré, évolutif et maintenable.