Le Factory Pattern est l'un des design patterns de création les plus utilisés en programmation orientée objet. Dans le contexte du développement .NET moderne, il permet de gérer efficacement la création d'objets complexes tout en maintenant un couplage faible entre les composants. Découvrons ensemble comment implémenter et utiliser ce pattern puissant en C#.
Comprendre le Factory Pattern
Le Factory Pattern propose une approche élégante pour déléguer la création d'objets à une classe spécialisée, appelée "factory". Cette abstraction permet de masquer la complexité de l'instanciation et offre une interface unifiée pour créer différents types d'objets.
Les variantes principales
- Simple Factory : Pattern de base qui centralise la création d'objets
- Factory Method : Définit une interface pour la création d'objets mais laisse les sous-classes décider quelle classe instancier
- Abstract Factory : Permet de créer des familles d'objets reliés sans spécifier leurs classes concrètes
Implémentation du Simple Factory
// Interface commune pour tous les produits
public interface IVehicle
{
void Start();
void Stop();
}
// Implémentations concrètes
public class Car : IVehicle
{
public void Start() => Console.WriteLine("Car starting...");
public void Stop() => Console.WriteLine("Car stopping...");
}
public class Motorcycle : IVehicle
{
public void Start() => Console.WriteLine("Motorcycle starting...");
public void Stop() => Console.WriteLine("Motorcycle stopping...");
}
// Simple Factory
public class VehicleFactory
{
public IVehicle CreateVehicle(string vehicleType)
{
return vehicleType.ToLower() switch
{
"car" => new Car(),
"motorcycle" => new Motorcycle(),
_ => throw new ArgumentException("Invalid vehicle type")
};
}
}
Implémentation du Factory Method
public abstract class VehicleCreator
{
public abstract IVehicle CreateVehicle();
public void DeliverVehicle()
{
var vehicle = CreateVehicle();
vehicle.Start();
// Logique commune...
vehicle.Stop();
}
}
public class CarCreator : VehicleCreator
{
public override IVehicle CreateVehicle() => new Car();
}
public class MotorcycleCreator : VehicleCreator
{
public override IVehicle CreateVehicle() => new Motorcycle();
}
Implémentation de l'Abstract Factory
public interface IVehicleFactory
{
IEngine CreateEngine();
IBody CreateBody();
}
public class LuxuryVehicleFactory : IVehicleFactory
{
public IEngine CreateEngine() => new V8Engine();
public IBody CreateBody() => new PremiumBody();
}
public class EconomyVehicleFactory : IVehicleFactory
{
public IEngine CreateEngine() => new FourCylinderEngine();
public IBody CreateBody() => new BasicBody();
}
Bonnes Pratiques
- Utilisez des interfaces pour définir les contrats
- Favorisez l'injection de dépendances avec les factories
- Implémentez une gestion d'erreurs robuste
- Documentez les types supportés par la factory
Intégration avec .NET DI
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton();
services.AddScoped();
}
Tests Unitaires
public class VehicleFactoryTests
{
private readonly VehicleFactory _factory;
public VehicleFactoryTests()
{
_factory = new VehicleFactory();
}
[Fact]
public void CreateVehicle_WhenTypeCar_ReturnsCar()
{
var vehicle = _factory.CreateVehicle("car");
Assert.IsType(vehicle);
}
[Fact]
public void CreateVehicle_WhenInvalidType_ThrowsArgumentException()
{
Assert.Throws(() =>
_factory.CreateVehicle("invalid"));
}
}
Cas d'Usage Réels
Le Factory Pattern est particulièrement utile dans les scénarios suivants :
- Création de connexions à différentes bases de données
- Génération de rapports dans différents formats
- Instanciation de services selon la configuration
- Création de clients API avec différentes authentifications
Performance et Optimisation
Pour optimiser les performances lors de l'utilisation du Factory Pattern :
- Utilisez le pooling d'objets pour les instances fréquemment créées
- Implémentez le lazy loading quand approprié
- Considérez l'utilisation de cache pour les objets coûteux à créer
Conclusion
Le Factory Pattern est un outil essentiel dans le développement .NET moderne. Il offre une solution élégante pour la création d'objets tout en maintenant un code propre et maintenable. En suivant les bonnes pratiques et en comprenant les différentes variantes, vous pouvez l'utiliser efficacement dans vos projets.
N'oubliez pas que le choix de la variante du pattern dépend de vos besoins spécifiques. Le Simple Factory convient aux cas simples, tandis que l'Abstract Factory est préférable pour des systèmes plus complexes nécessitant la création de familles d'objets.