Modèle de méthode d'usine : relever les défis de gestion des dépendances avec DI/IoC
Le modèle Factory Method, amélioré par l'injection de dépendances (DI) et l'inversion de contrôle (IoC), offre une abstraction élégante pour la création d'objets. Cependant, gérer de nombreuses dépendances au sein du constructeur de l'usine peut devenir problématique. Cet article explore des solutions à ce défi commun.
Le problème : les constructeurs d'usines trop complexes
Un CarFactory
avec un constructeur nécessitant de nombreuses dépendances illustre ce problème. Cette conception contredit l'objectif de la méthode Factory consistant à encapsuler la logique de création et à l'isoler des détails des dépendances. L'injection manuelle de chaque dépendance devient lourde à mesure que la variété des types de voitures augmente.
Solutions : approches raffinées
Deux approches clés offrent une meilleure gestion des dépendances :
Approche 1 : Injection de conteneurs
Cela simplifie le constructeur d'usine en injectant un conteneur de service chargé de résoudre dynamiquement les dépendances. Cela réduit les dépendances directes de l'usine :
public class CarFactory { private readonly IContainer _container; public CarFactory(IContainer container) { _container = container; } public ICar CreateCar(Type type) { // Resolve dependencies via the container switch (type) { case Type a: return _container.Resolve<ICar1>(); case Type b: return _container.Resolve<ICar2>(); default: throw new ArgumentException("Unsupported car type."); } } }
Bien qu'efficace, cette approche introduit le recours à un localisateur de services.
Approche 2 : Le modèle de stratégie – Une solution plus élégante
Le modèle Strategy offre une solution supérieure en dissociant l'interface de l'usine de son implémentation. Cela permet d'enregistrer plusieurs usines et de les sélectionner dynamiquement en fonction du type d'objet :
Interfaces :
public interface ICarFactory { ICar CreateCar(); bool AppliesTo(Type type); } public interface ICarStrategy { ICar CreateCar(Type type); }
Usines à béton (exemples) :
public class Car1Factory : ICarFactory { // Dependencies injected into the factory public Car1Factory(IDep1 dep1, IDep2 dep2, IDep3 dep3) { ... } public ICar CreateCar() { ... } public bool AppliesTo(Type type) { ... } } public class Car2Factory : ICarFactory { ... }
La stratégie :
public class CarStrategy : ICarStrategy { private readonly ICarFactory[] _carFactories; public CarStrategy(ICarFactory[] carFactories) { _carFactories = carFactories; } public ICar CreateCar(Type type) { var factory = _carFactories.FirstOrDefault(f => f.AppliesTo(type)); if (factory == null) throw new InvalidOperationException("No factory registered for type " + type); return factory.CreateCar(); } }
Utilisation :
var strategy = new CarStrategy(new ICarFactory[] { new Car1Factory(dep1, dep2, dep3), new Car2Factory(dep4, dep5, dep6) }); var car1 = strategy.CreateCar(typeof(Car1)); var car2 = strategy.CreateCar(typeof(Car2));
Cette approche offre flexibilité et extensibilité, permettant un enregistrement facile de nouvelles usines et une création d'objets rationalisée. Il sépare efficacement la logique de création des dépendances, simplifiant ainsi le développement et la maintenance de relations complexes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!