Création : Factory, Builder, Singleton (avec modération)
Créer des objets a l'air trivial jusqu'au jour où la construction se disperse (10 new X(a, b, null, true) illisibles) ou se duplique (mêmes 15 lignes d'init partout).
Prérequis : cours 1.3.
Pourquoi
Créer des objets a l'air trivial jusqu'au jour où la construction se disperse (10 new X(a, b, null, true) illisibles) ou se duplique (mêmes 15 lignes d'init partout). Les patterns de création centralisent le « comment naître ».
Concepts
- Factory : une fonction/méthode qui choisit quoi construire (
createNotifier(type)→ Email/SMS). Le client ne connaît que l'interface, jamais les classes concrètes — OCP naturel. - Builder : construction par étapes lisibles pour objets complexes (
new Query().select().where().limit()). Adieu les constructeurs à 9 paramètres et lesnullmystères. - Singleton : une seule instance (config, pool). À manier avec des pincettes : état global déguisé = tests qui se contaminent. Préférer : instance unique injectée (même effet, testable).
Exemple : Builder vs télescopique
// Télescopique illisible :
new Report(user, null, true, false, "pdf", null, true);
// Builder :
Report.for(user).asPdf().withCharts().withoutDrafts().build();
Cas réel
Connexions base créées « à la volée » dans chaque handler : 200 connexions sous charge, base à genoux. Pool unique injecté (singleton de fait, pas de pattern) : 20 connexions, problème disparu.
Pièges
- Singleton pour « simplifier » : état global = tests fragiles + couplage caché. Injecter l'instance unique.
- Factory qui connaît tout : si elle grossit, c'est un registre (map nom → constructeur), pas une usine à if.
- Builder pour 2 paramètres : YAGNI, le pattern doit matcher la complexité réelle.
À retenir
Factory = choisir sans connaître, Builder = lisible à N paramètres, Singleton = instance injectée, pas global.