Modèles de conception en TypeScript : du simple au complexe
Les modèles de conception (design patterns) sont des solutions éprouvées par le temps pour résoudre des problèmes typiques dans le développement de logiciels. Dans le contexte de TypeScript, qui ajoute à JavaScript un typage strict et des capacités de POO, les modèles deviennent particulièrement efficaces. TypeScript permet d'implémenter des abstractions, des interfaces et du polymorphisme à un nouveau niveau, rendant le code plus prévisible et plus sûr.
Dans cet article, nous analyserons les modèles de conception clés, leur implémentation en TypeScript et des exemples pratiques d'utilisation. Ce contenu sera utile aussi bien aux développeurs débutants qu'aux spécialistes expérimentés souhaitant systématiser leurs connaissances.
Modèles de création : Singleton et Factory Method
Les modèles de création sont responsables de la création d'objets, en masquant la logique d'instanciation. Examinons les deux représentants les plus populaires : Singleton et Factory Method.
Singleton (Singleton)
Singleton garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à celle-ci. En TypeScript, l'implémentation devient particulièrement élégante grâce aux membres statiques et aux constructeurs privés.
class DatabaseConnection { private static instance: DatabaseConnection; private connectionString: string;
private constructor(connectionString: string) { this.connectionString = connectionString; console.log(`Connexion créée avec : ${connectionString}`); }
static getInstance(connectionString: string): DatabaseConnection { if (!DatabaseConnection.instance) { DatabaseConnection.instance = new DatabaseConnection(connectionString); } return DatabaseConnection.instance; }
query(sql: string): void { console.log(`Exécution de la requête : ${sql} sur ${this.connectionString}`); }}
// Utilisationconst db1 = DatabaseConnection.getInstance('postgres://localhost:5432/mydb');const db2 = DatabaseConnection.getInstance('postgres://localhost:5432/mydb');console.log(db1 === db2); // true - le même objetCe modèle est idéal pour la gestion des ressources : pools de connexions, journalisation, mise en cache. Cependant, soyez prudent — Singleton peut compliquer les tests en raison de l'état global.
Factory Method (Méthode de fabrique)
Factory Method définit une interface pour créer un objet, mais permet aux sous-classes de modifier le type d'objet créé. En TypeScript, cela est implémenté via des classes abstraites ou des interfaces.
interface Notification { send(message: string): void;}
class EmailNotification implements Notification { send(message: string): void { console.log(`Envoi d'email : ${message}`); }}
class SMSNotification implements Notification { send(message: string): void { console.log(`Envoi de SMS : ${message}`); }}
abstract class NotificationFactory { abstract createNotification(): Notification;
notify(message: string): void { const notification = this.createNotification(); notification.send(message); }}
class EmailFactory extends NotificationFactory { createNotification(): Notification { return new EmailNotification(); }}
class SMSFactory extends NotificationFactory { createNotification(): Notification { return new SMSNotification(); }}
// Utilisationconst factory: NotificationFactory = new EmailFactory();factory.notify('Votre commande est confirmée !');Factory Method aide à respecter le principe d'ouverture/fermeture (OCP) — vous pouvez ajouter de nouveaux types de notifications sans modifier le code existant.
Modèles structurels : Adapter et Decorator
Les modèles structurels aident à organiser les relations entre les objets et les classes, rendant le système plus flexible et extensible.