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 IMotor
avec des types concrets Motor1
et Motor2
, qui devrait être géré par une usine. Il y a maintenant deux façons de décider comment configurer mon appareil:
- Je passe des informations sur le dispositif que le SW est en cours d' exécution à un
MotorFactory
et il renvoie le moteur correct, que ce soitMotor1
ouMotor2
. Dans ce cas, la logique de décision est à l' intérieur de l'usine. - Je configure le DIC en fonction de l'appareil sur lequel il fonctionne et crée deux usines
Motor1Factory
etMotor2Factory
, où l'une créeMotor1
et l'autreMotor2
. Dans ce cas, j'aurais des entrées de registre différentes pourIMotor
les registres spécifiques au périphérique qui utilisent soitMotor1Factory
ouMotor2Factory
.
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?
la source
Réponses:
Si vous utilisez les deux, je choisirai quelque chose de simple:
la source
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
Motor1
etMotor2
aujourd'hui, il y en aura peut-être demainMotor3
. Privilégiez le design qui seraitMotor3
facile à ajouter.la source
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:
la source