Conteneur DI / IoC vs usines: où dois-je configurer mon application et pourquoi?

9

J'essaie de comprendre quand utiliser le registre DIC / IoC pour configurer mon logiciel et quand utiliser des usines, ainsi que le raisonnement derrière l'une ou l'autre approche.


J'utilise StructureMap comme mon conteneur DI (DIC), qui est facile à configurer à l'aide de registres. Dans le DIC, pratiquement tous les objets enregistrés sont statiques dans le sens où je n'ai pas besoin de changer / échanger d'implémentation / instance au moment de l'exécution, une fois le DIC configuré et ils sont configurés dans le DIC en tant que singletons. Cependant, étant donné que mon logiciel (SW) s'exécutera sur différents appareils, je dois sélectionner un registre spécifique à l'appareil en fonction de l'appareil sur lequel mon SW s'exécute afin de configurer le matériel en conséquence.

Étant donné que la construction de certains de mes objets nécessite la lecture des fichiers de configuration, j'utilise des usines pour renvoyer ces instances au DIC, afin de séparer la lecture de la configuration de la création de l'objet. J'ai enregistré les getters d'usine dans le DIC pour les types de plugins correspondants.

Disons maintenant que j'ai un type de plugin IMotoravec des types concrets Motor1et Motor2, qui devrait être géré par une usine. Il y a maintenant deux façons de décider comment configurer mon appareil:

  1. Je passe des informations sur le dispositif que le SW est en cours d' exécution à un MotorFactoryet il renvoie le moteur correct, que ce soit Motor1ou Motor2. Dans ce cas, la logique de décision est à l' intérieur de l'usine.
  2. Je configure le DIC en fonction de l'appareil sur lequel il fonctionne et crée deux usines Motor1Factoryet Motor2Factory, où l'une crée Motor1et l'autre Motor2. Dans ce cas, j'aurais des entrées de registre différentes pour IMotorles registres spécifiques au périphérique qui utilisent soit Motor1Factoryou Motor2Factory.

Maintenant ma question est: laquelle de ces deux méthodes est préférable et pourquoi? Pour moi, il semble que le premier cas ne soit pas simple et compliqué, car j'étends la logique qui décide du type à instancier dans la base de code. Alors que dans le second cas, je multiplie effectivement le nombre d'usines dans mon code, car j'aurai besoin d'une usine pour (presque) chaque type de béton. Cela devient encore plus déroutant pour moi, lorsque des usines abstraites sont ajoutées au mélange.

Encore une fois: quand dois-je utiliser une méthode ou l'autre? Et plus important encore: quels sont les bons indicateurs pour décider de la voie à suivre?

packoman
la source
2
Quelle voie est plus simple? Les avantages de l'approche plus complexe l'emportent-ils sur le coût de la complexité supplémentaire?
Robert Harvey

Réponses:

2

Si vous utilisez les deux, je choisirai quelque chose de simple:

  • DI / IoC: pour chaque configuration qui ne changera pas au moment de l'exécution.
  • Usine: pour créer une instance d'objets à l'exécution qui dépend des paramètres d'entrée d'exécution. Les instances de l'usine sont injectées par le conteneur DI.
Walfrat
la source
1

Les usines abstraites sont utilisées lorsque vous avez des objets liés à travers une hiérarchie qui doit varier ensemble. Je ne vois pas ça ici.

Ce que je vois, c'est que vous vous demandez si une usine devrait choisir le moteur ou si le DIC devrait choisir une usine qui produit un moteur particulier.

Il est difficile de choisir précisément parce qu'une usine et un DIC font des choses très similaires. La différence est que l'usine se concentre sur un problème particulier et que le DIC est plus général.

Cela revient à cette question: avez-vous besoin d'un code spécifique à ce problème qui vivra en usine? Ou est-ce plus général comme lire les détails de configuration d'un fichier?

Gardez à l'esprit que si vous ne choisissez qu'entre aujourd'hui Motor1et Motor2aujourd'hui, il y en aura peut-être demain Motor3. Privilégiez le design qui serait Motor3facile à ajouter.

candied_orange
la source
0

Je séparerais la logique "quel moteur utiliser" dans une usine spéciale appelée Builder (modèle) et utiliserais le conteneur IOC pour les deux moteurs comme détail d'implémentation du constructeur.

En règle générale:

  • vous avez besoin d'une fabrique (ou d'un constructeur) si vous devez créer de nombreux objets dynamiques de la classe / interface. (c'est-à-dire que pour chaque voiture que vous produisez, vous devez créer un nouveau moteur)
  • si vous n'avez besoin que d'une seule instance statique d'une classe, l'ioc / di peut faire le travail pour vous (c'est-à-dire que vous n'avez besoin que d'une seule instance statique du services de paiement et d'une instance statique du MotorBuilderService)
k3b
la source