Factory Pattern (Patron Fabrique)
Pattern de création orienté objet permettant d'instancier des objets sans spécifier leur classe exacte, favorisant le découplage et flexibilité.
Mis à jour le 9 janvier 2026
Le Factory Pattern est un patron de conception créationnel qui délègue la logique d'instanciation à une classe ou méthode dédiée, plutôt que d'utiliser directement l'opérateur 'new'. Ce pattern permet de créer des objets de manière flexible en encapsulant la complexité de leur création et en favorisant le principe de responsabilité unique. Il s'avère particulièrement utile lorsque la classe exacte d'un objet n'est connue qu'à l'exécution ou lorsque plusieurs variantes d'un même type d'objet doivent être créées selon différents contextes.
Fondements du Pattern
- Encapsulation de la logique de création d'objets dans une méthode ou classe dédiée
- Séparation entre l'interface de création et l'implémentation concrète des classes
- Respect du principe ouvert/fermé : extensible sans modifier le code client existant
- Abstraction des dépendances concrètes au profit d'interfaces ou de classes abstraites
Avantages Business et Techniques
- Facilite l'évolution du code en centralisant la logique de création dans un point unique
- Réduit le couplage entre les composants, améliorant la testabilité et la maintenabilité
- Permet l'ajout de nouvelles variantes d'objets sans impacter le code client
- Simplifie la gestion de configurations complexes ou de dépendances conditionnelles
- Améliore la lisibilité en rendant explicite l'intention de création d'objets métier
Exemple Concret en TypeScript
// Interface commune pour tous les processeurs de paiement
interface PaymentProcessor {
processPayment(amount: number): Promise<PaymentResult>;
getProviderName(): string;
}
interface PaymentResult {
success: boolean;
transactionId: string;
}
// Implémentations concrètes
class StripeProcessor implements PaymentProcessor {
async processPayment(amount: number): Promise<PaymentResult> {
// Logique Stripe
return { success: true, transactionId: 'stripe_' + Date.now() };
}
getProviderName(): string { return 'Stripe'; }
}
class PayPalProcessor implements PaymentProcessor {
async processPayment(amount: number): Promise<PaymentResult> {
// Logique PayPal
return { success: true, transactionId: 'paypal_' + Date.now() };
}
getProviderName(): string { return 'PayPal'; }
}
class CryptoProcessor implements PaymentProcessor {
async processPayment(amount: number): Promise<PaymentResult> {
// Logique Crypto
return { success: true, transactionId: 'crypto_' + Date.now() };
}
getProviderName(): string { return 'Crypto'; }
}
// Factory
class PaymentProcessorFactory {
static create(provider: 'stripe' | 'paypal' | 'crypto'): PaymentProcessor {
switch (provider) {
case 'stripe':
return new StripeProcessor();
case 'paypal':
return new PayPalProcessor();
case 'crypto':
return new CryptoProcessor();
default:
throw new Error(`Provider ${provider} not supported`);
}
}
}
// Utilisation dans le code client
const processor = PaymentProcessorFactory.create('stripe');
await processor.processPayment(99.99);Mise en Œuvre Efficace
- Identifier les familles d'objets partageant une interface ou classe abstraite commune
- Créer une factory method ou classe factory dédiée à l'instanciation de ces objets
- Implémenter la logique de sélection basée sur des paramètres (type, configuration, contexte)
- Remplacer les appels directs au constructeur par des appels à la factory dans le code client
- Documenter les types d'objets disponibles et leurs cas d'usage respectifs
- Ajouter des tests unitaires pour vérifier que la factory retourne les bonnes instances
Conseil Pro
Combinez le Factory Pattern avec l'injection de dépendances pour une architecture encore plus flexible. Enregistrez vos factories dans un conteneur IoC, permettant ainsi de changer dynamiquement les stratégies de création sans modifier le code métier. Pour les applications complexes, considérez l'Abstract Factory Pattern pour gérer des familles d'objets liés.
Outils et Frameworks Associés
- TypeScript et ses types génériques pour créer des factories type-safe
- InversifyJS ou TSyringe pour l'injection de dépendances avec factory bindings
- NestJS qui intègre nativement le pattern avec les custom providers
- Factory Bot (Ruby) ou Factory Boy (Python) pour générer des fixtures de test
- Builder Pattern en complément pour gérer la construction complexe d'objets
Le Factory Pattern représente un investissement stratégique dans la qualité du code, réduisant significativement les coûts de maintenance à long terme. En centralisant la logique de création, il facilite les évolutions métier (ajout de nouveaux fournisseurs, types de produits) et améliore la couverture de tests en isolant les dépendances. Pour les équipes modernes, ce pattern constitue une brique essentielle d'une architecture scalable et résiliente face aux changements.
