Injection de dépendance par rapport au modèle de L'usine

la plupart des exemples cités pour L'utilisation de L'Injection de dépendances, nous pouvons résoudre en utilisant le modèle d'usine aussi bien. On dirait que quand il s'agit d'utilisation/design la différence entre l'injection de dépendance et l'usine est floue ou mince.

une fois quelqu'un m'a dit que c'est la façon dont vous l'utilisez qui fait une différence!

j'ai déjà utilisé StructureMap un conteneur DI pour résoudre un problème, plus tard, je l'ai redessiné pour travailler avec un simple usine et supprimé les références à StructureMap.

quelqu'un Peut-il me dire quelle est la différence entre eux et ce, quelle est la meilleure pratique ici?

423
demandé sur Binoj Antony 2009-02-17 20:03:45
la source

27 ответов

lors de l'utilisation d'une usine, votre code est toujours responsable de la création des objets. En DI vous externalisez cette responsabilité à une autre classe ou un cadre, qui est séparé de votre code.

255
répondu willcodejavaforfood 2012-11-29 22:56:05
la source

je suggère de garder les concepts clairs et simples. L'Injection de dépendances est plus un modèle d'architecture pour coupler librement les composants logiciels. Factory pattern est juste une façon de séparer la responsabilité de créer des objets d'autres classes à une autre entité. Modèle d'usine peut être appelé comme un outil pour mettre en œuvre DI. L'injection de dépendances peut être implémentée de plusieurs façons comme DI en utilisant des constructeurs, en utilisant des fichiers XML de mappage, etc.

196
répondu Perpetualcoder 2009-02-17 20:10:28
la source

Injection De Dépendance

au lieu d'instancier les pièces lui-même une voiture demande pour les pièces dont il a besoin pour fonctionner.

class Car
{
    private Engine;
    private SteeringWheel;
    private Tires tires;

    public Car(Engine engine, SteeringWheel wheel, Tires tires)
    {
        this.Engine = engine;
        this.SteeringWheel = wheel;
        this.Tires = tires;
    }
}

Usine

rassemble les morceaux pour faire un objet complet et cache le type de béton de l'appelant.

static class CarFactory
{
    public ICar BuildCar()
    {
        Engine engine = new Engine();
        SteeringWheel steeringWheel = new SteeringWheel();
        Tires tires = new Tires();
        ICar car = new RaceCar(engine, steeringWheel, tires);
        return car;
    }   
}

résultat

comme vous pouvez le voir, les usines et DI se complètent.

static void Main()
{
     ICar car = CarFactory.BuildCar();
     // use car
}

vous souvenez-vous de boucles d'or et des trois ours? L'injection de dépendance est un peu comme ça. Voici trois façons de faire la même chose.

void RaceCar() // example #1
{
    ICar car = CarFactory.BuildCar();
    car.Race();
}

void RaceCar(ICarFactory carFactory) // example #2
{
    ICar car = carFactory.BuildCar();
    car.Race();
}

void RaceCar(ICar car) // example #3
{
    car.Race();
}

exemple #1 - c'est le pire parce qu'il cache complètement la dépendance. Si vous avez regardé la méthode comme une boîte noire vous n'avez aucune idée de ce requis voiture.

exemple #2 - c'est un peu mieux parce que maintenant nous savons que nous avons besoin d'une voiture puisque nous passons dans une usine automobile. Mais cette fois, nous passons trop de depuis tous la méthode réellement besoin d'une voiture. Nous passons dans une usine juste pour construire la voiture alors que la voiture pourrait être construite en dehors de la méthode et passé dans.

exemple #3 - c'est idéal parce que la méthode demande exactement ce dont elle a besoin. Ni trop, ni trop peu. Je n'ai pas besoin d'écrire un MockCarFactory juste pour créer des Mockcar, je peux passer la maquette directement. C'est direct et l'interface ne ment pas.

Ce Google Tech Talk de Misko Hevery est étonnant et est la base de ce que j'ai dérivé mon exemple à partir. http://www.youtube.com/watch?v=XcT4yYu_TTs

153
répondu Despertar 2016-09-06 05:50:07
la source

il y a des problèmes qui sont faciles à résoudre avec l'injection de dépendances qui ne sont pas aussi facilement résolus avec une suite d'usines.

une partie de la différence entre, d'une part, l'inversion du contrôle et l'injection de dépendances (IOC/DI), et, d'autre part, un localisateur de service ou une suite d'usines (usine), est:

IOC / DI est un écosystème complet d'objets et de services de domaine en soi. Il met tout en place pour vous dans le manière que vous indiquez. Vos objets et services de domaine sont construits par le conteneur, et ne se construisent pas eux-mêmes: ils n'ont donc aucune dépendances sur le conteneur ou sur des usines. IOC / DI permet un degré extrêmement élevé de configurabilité, avec toute la configuration en un seul endroit (construction du conteneur) à la couche la plus haute de votre application (L'interface graphique, le front-end Web).

Usine abstraction de certains de la construction de vos objets et services de domaine. Mais les objets de domaine et les services sont toujours responsables de comprendre comment se construire et comment obtenir toutes les choses dont ils dépendent. Toutes ces dépendances" actives " filtrent toutes les couches de votre application. Il n'y a pas un seul endroit pour tout configurer.

38
répondu yfeldblum 2009-02-17 20:16:50
la source

un inconvénient de DI est qu'il ne peut pas initialiser les objets avec la logique. Par exemple, quand j'ai besoin de créer un personnage qui a un nom aléatoire et l'âge, DI n'est pas le choix sur le modèle d'usine. Avec les usines, nous pouvons facilement encapsuler l'algorithme aléatoire de la création d'objet, qui soutient un des modèles de conception appelé "encapsuler ce qui varie".

21
répondu BinMaster 2012-05-01 13:24:19
la source

la gestion du cycle de vie est l'une des responsabilités assumées par les conteneurs dépendants en plus de l'instanciation et de l'injection. Le fait que le conteneur conserve parfois une référence aux composants Après instanciation est la raison pour laquelle il est appelé un "conteneur", et non une usine. Les conteneurs d'injection de dépendances ne conservent généralement qu'une référence aux objets dont ils ont besoin pour gérer les cycles de vie, ou qui sont réutilisés pour de futures injections, comme des singletons ou des poids volants. Lorsque configuré pour créer de nouvelles instances de certains composants pour chaque appel du conteneur, le conteneur habituellement juste oublie de l'objet créé.

de: http://tutorials.jenkov.com/dependency-injection/dependency-injection-containers.html

20
répondu Pup 2010-12-20 23:09:28
la source

la raison pour laquelle les modes D'Injection de dépendance (DI) et D'usine sont similaires est qu'il s'agit de deux implémentations d'Inversion de contrôle (IoC) qui est une architecture logicielle. En d'autres termes, il s'agit de deux solutions au même problème.

ainsi pour répondre à la question la principale différence entre le modèle D'usine et DI est la façon dont la référence de l'objet est obtenue. Avec l'injection de dépendances comme son nom l'indique, la référence est injectée ou donnée à votre code. Avec Modèle d'usine votre code doit demander la référence afin que votre code récupère l'objet. Les deux implémentations suppriment ou découplent le lien entre le code et la classe ou le type sous-jacent de la référence d'objet utilisée par le code.

il est intéressant de noter que les modèles D'usine (ou en fait les modèles D'usine abstraits qui sont des usines qui renvoient de nouvelles usines qui renvoient des références à des objets) peuvent être écrits dynamiquement pour choisir ou lier au type ou à la classe d'être objet demandé au moment de l'exécution. Cela les rend très similaires (encore plus que DI) au modèle de localisateur de Service qui est une autre implémentation du CIO.

le modèle de conception de L'usine est assez ancien (en termes de Logiciel) et a été autour pendant un certain temps. Depuis la popularité récente du modèle architectural IoC, il connaît une résurgence.

je suppose qu'en ce qui concerne les schémas de conception du COI: les injecteurs s'injectent, les localisateurs sont localisés et les usines ont été refait.

20
répondu Tom Maher 2015-03-19 14:38:21
la source

je crois que DI est un type de couche d'abstraction sur les usines, mais ils fournissent aussi des avantages au-delà de l'abstraction. Une vraie usine sait instancier un seul type et le configurer. Une bonne couche DI permet, par le biais de la configuration, d'instancier et de configurer de nombreux types.

évidemment, pour un projet avec quelques types simples qui nécessite une logique commerciale relativement stable dans leur construction, le modèle d'usine est simple à comprendre, mettre en œuvre, et fonctionne bien.

OTOH, si vous avez un projet contenant de nombreux types dont les implémentations vous attendez à changer souvent, DI Vous donne la flexibilité par sa configuration de le faire à l'exécution sans avoir à recompiler vos usines.

16
répondu Will 2009-02-17 20:13:04
la source

je sais que cette question Est ancienne mais je voudrais ajouter mes cinq cents,

je pense que l'injection de dépendance (DI) est à bien des égards comme un modèle d'usine configurable (FP), et dans ce sens tout ce que vous pouvez faire avec DI vous serez en mesure de le faire avec une telle usine.

en fait, si vous utilisez le ressort par exemple, vous avez l'option d'autowiring resources (DI) ou de faire quelque chose comme ceci:

MyBean mb = ctx.getBean("myBean");

et puis utilisez cette instance' mb ' pour faire n'importe quoi. N'est-ce pas un appel à une usine qui vous rendra une instance??

la seule vraie différence que je remarque entre la plupart des exemples FP est que vous pouvez configurer ce que "myBean" est dans un xml ou dans une autre classe, et un cadre fonctionnera comme l'usine, mais autre que cela est la même chose, et vous pouvez certainement avoir une usine qui lit un fichier de configuration ou obtient l'implémentation comme il le faut.

et si vous me demandez mon avis (et je sais que vous ne l'avez pas fait), je crois que DI fait la même chose, mais ajoute juste plus de complexité au développement, pourquoi?

Eh bien, pour une chose, pour que vous sachiez quelle est l'implémentation utilisée pour chaque bean que vous autorisez avec DI, vous devez aller à la configuration elle-même.

mais... que dire de cette promesse que vous n'aurez pas à savoir la mise en œuvre de l'objet que vous utilisez? plouf! sérieusement? lorsque vous utilisez un l'approche de ce genre... n'êtes-vous pas le même qui écrit l'implémentation?? et même si vous ne le faites pas, vous ne regardez pas presque tout le temps comment la mise en œuvre fait ce qu'elle est censée faire??

et pour une dernière chose, il n'importe pas combien un cadre DI promet vous que vous construirez des choses découplé à partir de lui, sans dépendances à leurs classes, si vous utilisez un cadre vous construisez tout à c', si vous devez changer l'approche ou le cadre, il ne sera pas une tâche facile... JAMAIS! ... mais, puisque vous construisez tout autour de ce cadre particulier au lieu de se soucier de ce qui est la meilleure solution pour votre entreprise, alors vous allez faire face à un biiig problen en faisant cela.

en fait, la seule vraie application d'affaires pour une approche FP ou DI que je peux voir est si vous avez besoin de changer les implémentations utilisées à runtime , mais au moins les cadres que je connais ne vous permettent pas de le faire, vous devez tout laisser parfait dans la configuration au moment du développement et si vous avez besoin qui utilisent une autre approche.

donc, si j'ai une classe qui fonctionne différemment dans deux portées dans la même application (disons, deux entreprises d'une holding) je dois configurer le cadre pour créer deux haricots différents, et adapter mon code pour utiliser chacun. N'est-ce pas la même chose que si je voudrais juste écrire quelque chose comme ceci:

MyBean mb = MyBeanForEntreprise1(); //In the classes of the first enterprise
MyBean mb = MyBeanForEntreprise2(); //In the classes of the second enterprise

comme ceci:

@Autowired MyBean mbForEnterprise1; //In the classes of the first enterprise
@Autowired MyBean mbForEnterprise2; //In the classes of the second enterprise

et ceci:

MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise1"); //In the classes of the first enterprise
MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise2"); //In the classes of the second enterprise

dans tous les cas, vous devrez changer quelque chose dans votre application, qu'il s'agisse de classes ou de fichiers de configuration, mais vous devrez le redéployer.

ce ne serait pas bien de faire quelque chose comme ça:

MyBean mb = (MyBean)MyFactory.get("mb"); 

et de cette façon, vous définissez le code de l'usine pour obtenir la simple application du droit à l'exécution en fonction de l'utilisateur de l'entreprise?? Maintenant QUE ce serait utile. Vous pouvez simplement ajouter un nouveau jar avec les nouvelles classes et définir les règles peut-être même à l'exécution (ou ajouter un nouveau fichier de configuration si vous laissez cette option ouverte), aucun changement aux classes existantes. Ce serait une usine dynamique!

ne serait pas plus utile que d'avoir à écrire deux configurations pour chaque entreprise, et peut-être même avoir deux applications différentes pour chacun d'entre eux??

vous pouvez me le dire, je n'ai pas besoin de faire le commutateur à l'exécution jamais, donc je configure l'application, et si j'hérite de la classe ou utiliser une autre implémentation je viens de changer la config et redéployer. Ok, cela peut aussi être fait avec une usine. Et sois honnête, combien de fois tu fais ça? peut-être seulement quand vous avez une application qui va être utilisé ailleurs dans votre entreprise, et vous allez passer le code à une autre équipe, et ils vont faire des choses comme ça. Mais bon, qui peut faites aussi avec l'usine, et ce serait encore mieux avec une usine dynamique!!

quoi qu'il en soit, la section des commentaires est ouverte pour que vous me tuiez.

11
répondu Frank Orellana 2012-09-13 09:02:57
la source

théorie

il y a deux points importants à considérer:

  1. qui crée des objets

    • [Factory]: vous devez écrire comment l'objet doit être créé. Vous avez une classe D'usine séparée qui contient la logique de création.
    • [injection de dépendances]: dans la pratique, l'Injection est effectuée par des cadres externes (par exemple en Java qui serait spring/ejb/guice). Injection se produit "par magie" sans création explicite de nouveaux objets
  2. Quel genre d'objets gère-t-il:

    • [l'Usine]: Habituellement responsable de la création d'objets ayant
    • [Injections de dépendances] plus susceptibles de créer des objets apatrides

exemple pratique comment utiliser les deux injection en usine et de dépendance dans un seul projet

  1. ce que nous voulons construire

module d'Application pour la création de l'ordre qui contient plusieurs entrées appelé orderline.

  1. Architecture

supposons que nous voulons créer l'architecture de couches suivante:

enter image description here

les objets de domaine peuvent être des objets stockés dans la base de données. Le dépôt (DAO) aide à retrouver les objets de la base de données. Le Service fournit L'API à d'autres modules. Autorisations pour les opérations sur order module

  1. couche de domaine et usage des usines

les entités qui seront dans la base de données sont Order et OrderLine. L'ordre peut avoir plusieurs lignes de commande. Relationship between Order and OrderLine

vient maintenant partie importante de conception. Les modules extérieurs à celui-ci devraient-ils créer et gérer eux-mêmes les Lignesorder? Aucun. Ligne de commande doivent exister que lorsque vous avez la Commande associée. Il serait préférable que vous puissiez Cacher l'implémentation interne à des classes externes.

mais comment créer L'ordre sans connaissance des OrderLines?

Usine

Quelqu'un qui veut créer un nouvel ordre utilisé OrderFactory (qui cachez les détails sur la façon dont nous créons L'ordre).

enter image description here

C'est comme ça que ça aura l'air à L'intérieur D'IDE. Les classes à l'extérieur du colis domain utiliseront OrderFactory au lieu du constructeur à l'intérieur de Order

  1. Injection De Dépendance L'injection de dépendances est plus couramment utilisée avec les couches apatrides telles que le dépôt et le service.

OrderRepository et OrderService sont gérés par dependency injection framework. Le dépôt est responsable de la gestion des opérations CRUD sur la base de données. Le service injecte le dépôt et l'utilise pour enregistrer/trouver les classes de domaine correctes.

enter image description here

9
répondu Marcin Szymczak 2017-05-29 15:59:27
la source

avec l'injection de dépendances le client n'a pas besoin d'obtenir ses dépendances par lui-même, tout préparé à l'avance.

Avec les usines, quelqu'un a appeler les pour obtenir les objets générés à l'endroit où ils sont nécessaires.

La différence réside principalement dans cette ligne où l'appel de l'usine et de l'extraction de l'objet construit est fait.

mais avec les usines vous devez écrire cette 1 ligne partout vous avez besoin d'un tel objet. Avec DI, il suffit de créer le câblage (relation entre l'usage et l'objet créé) une seule fois et de se fier à la présence de l'objet après partout. D'un autre côté, DI nécessite souvent un peu plus (combien dépend du cadre) de travail du côté de la préparation.

5
répondu Kosi2801 2009-02-17 20:12:34
la source

la COI est un concept qui est mis en œuvre de deux façons. Création de dépendances et injection de dépendances, usine/usine abstraite sont des exemples de création de dépendances. L'injection de dépendances est le constructeur, le setter et l'interface. Le noyau de la recherche des causes est de ne pas dépendre des classes concrètes, mais de définir l'abstrait des méthodes (disons une Interface/classe abstraite) et d'utiliser cet abstrait pour appeler la méthode de la classe concrète. Comme le modèle D'usine retourner la classe de base ou l'interface. Similariliy l'injection de dépendance utilise la classe de base / l'interface pour définir la valeur des objets.

5
répondu Thakur 2011-08-28 12:22:42
la source

j'ai eu la même question dès que j'ai lu au sujet de DI et a fini à ce poste. Donc finalement c'est ce que j'ai compris mais s'il vous plaît corrigez-moi si je me trompe.

" il y a longtemps, il y avait de petits royaumes avec leurs propres organes de gouvernement qui contrôlaient et prenaient des décisions basées sur leurs propres règles écrites. Plus tard formé un grand gouvernement éliminant tous ces petits organes de gouvernement qui a un ensemble de règles (constitution) et sont mis en œuvre par les tribunaux"

les organes de gouvernement des petits royaumes sont des "usines

le grand gouvernement est l' "injecteur de dépendance".

3
répondu blueskin 2010-12-21 01:23:43
la source

vous pouvez avoir un oeil à ce lien pour une comparaison des deux (et d'autres) approches dans un exemple réel.

en gros, lorsque les exigences changent, vous finissez par Modifier plus de code si vous utilisez des usines au lieu de DI.

ceci est également valable avec le DI manuel (c'est-à-dire lorsqu'il n'y a pas de framework externe qui fournit les dépendances à vos objets, mais que vous les passez dans chaque constructeur).

3
répondu Daniele Pallastrelli 2016-03-14 15:38:27
la source

je crois que DI est une façon de configurer ou instantianter un haricot. Le DI peut être fait de nombreuses façons comme constructeur, setter-getter, etc.

dessin D'usine est juste une autre façon d'instanciating haricots. Ce modèle sera utilisé principalement quand vous devez créer des objets en utilisant le modèle de conception d'usine, parce que tout en utilisant ce modèle vous ne configurez pas les propriétés d'un haricot, instanciez seulement l'objet.

vérifier ce lien: Injection De Dépendance

2
répondu harshit 2009-02-17 21:01:17
la source

Binoj,

Je ne pense pas que vous devez choisir l'un par rapport à l'autre.

le fait de déplacer une classe dépendante ou une interface vers un constructeur ou un setter de classe suit le modèle DI. L'objet que vous passez au constructeur ou à l'ensemble peut être implémenté avec L'usine.

quand utiliser? Utilisez le ou les modèles qui sont dans votre maison de maître. Avec quoi se sentent-ils le plus à l'aise et qu'ils trouvent le plus facile à comprendre?

2
répondu Jason Slocomb 2012-07-13 21:06:26
la source

mes pensées:

Dependecy Injection: passer les collaborateurs comme paramètres aux constructeurs. Dependency Injection Framework: une usine générique et configurable pour créer les objets à passer comme paramètres aux constructeurs.

1
répondu bloparod 2009-10-28 04:22:39
la source

un cadre D'Injection est une mise en œuvre du modèle D'usine.

tout dépend de vos exigences. Si vous avez besoin de mettre en œuvre le modèle d'usine dans une application, il est très probable que vos exigences seront satisfaites par l'une des myriades de mises en œuvre de cadre d'injection là-bas.

vous ne devez déployer votre propre solution que si vos exigences ne peuvent être satisfaites par aucun des cadres tiers. Le plus de code vous écrivez, Plus vous codez vous devez maintenir. Le Code est un passif et non un actif.

Arguments sur la mise en œuvre que vous devez utiliser n'est pas aussi fondamentalement important que la compréhension des besoins architecturaux de votre application.

1
répondu Mick 2013-06-17 06:23:11
la source

Dessin D'Usine

le dessin d'usine est caractérisé par

  • Une Interface
  • classes de mise en œuvre
  • une usine

vous pouvez observer peu de choses quand vous vous questionnez comme ci-dessous

  • quand l'usine créera - t-elle un objet pour les classes d'implémentation-lancer le temps ou compile le temps?
  • Que faire si vous voulez changer la mise en œuvre à l'exécution? - impossible
  • "

ceux-ci sont traités par injection de dépendance.

injection de dépendance

vous pouvez avoir différentes façons d'injecter la dépendance. Pour la simplicité laisse aller avec L'Injection D'Interface

Dans DI ,container crée les instances nécessaires, et les "injecte" dans l'objet.

élimine ainsi l'instanciation statique.

exemple:

public class MyClass{

  MyInterface find= null;

  //Constructor- During the object instantiation

  public MyClass(MyInterface myInterface ) {

       find = myInterface ;
  }

  public void myMethod(){

       find.doSomething();

  }
}
1
répondu Siva Kameswara Rao Munipalle 2014-09-24 15:51:40
la source

à partir d'une valeur faciale, ils se ressemblent

en termes très simples, dessin D'usine, Un dessin de création nous aide à créer un objet - "définir une interface pour créer un objet". Si nous avons une valeur de clé sorte de pool d'objet (par exemple Dictionnaire), en passant la clé à l'usine (je me réfère au Modèle D'usine Simple), vous pouvez résoudre le Type. Travail de fait! Cadre D'Injection de dépendances (tel que Structure Map, Ninject, Unity)...etc) sur le l'autre main semble faire la même chose.

Mais... "Ne pas réinventer la roue"

D'un point de vue architectural, c'est une couche de reliure et"ne pas réinventer la roue".

pour une application de grade Entreprise, le concept de DI est plus d'une couche architecturale qui définit les dépendances. Pour simplifier davantage, vous pouvez penser à cela comme un projet de bibliothèque de classe séparé, qui ne la dépendance résoudre. L'application principale dépend de ce projet où le résolveur de dépendances se réfère à d'autres implémentations concrètes et à la résolution de dépendances.

en plus de" GetType/Create " d'une usine, le plus souvent nous avons besoin de plus de fonctionnalités (capacité D'utiliser XML pour définir des dépendances, moqueries et tests unitaires, etc.). Puisque vous avez fait référence à la carte de Structure, regardez la Structure Carte liste des caractéristiques . Il est nettement plus que la simple résolution d'objet simple Cartographie. Ne pas réinventer la roue!

si tout ce que vous avez est un marteau, tout ressemble à un clou

selon vos exigences et le type d'application que vous construisez, vous devez faire un choix. Si elle n'a que peu de projets (peut être un ou deux..) et implique peu de dépendances, vous pouvez choisir une approche plus simple. C'est comme utiliser L'accès aux données ADO. NET en utilisant le cadre Entity pour un simple appel de base de données 1 ou 2, où l'introduction de L'EF est une exagération dans ce scénario.

mais pour un projet plus grand ou si votre projet devient plus grand, je recommande fortement d'avoir une couche DI avec un cadre et faire de la place pour changer le cadre DI que vous utilisez (utilisez une façade dans L'application principale (application Web, Api Web, Bureau..etc.).

1
répondu Dhanuka777 2016-09-09 17:50:53
la source

je crois, 3 aspects importants régissent les objets et leur usage:

1. Instantiation (d'une classe avec éventuellement une initialisation).

2. Injection (de l'instance ainsi créée) où elle est requise.

3. gestion du cycle de vie (de l'instance ainsi créée).



À l'aide de modèle de Fabrique, l' premier aspect (instanciation) est atteint, mais les deux autres sont discutables. La classe qui utilise d'autres instances doit hardcode les usines (au lieu des instances étant créées) qui empêche les capacités de couplage lâche. En outre, gestion du cycle de vie des instances devient un défi dans une grande application où une usine est utilisée dans plusieurs endroits (en particulier, si l'usine ne gère pas le cycle de vie de l'instance qu'il renvoie, il devient laid).



En utilisant un DI (de modèle de IoC) d'autre part, tous les 3 sont abstraits en dehors du code (au conteneur DI) et le haricot géré n'a pas besoin de cette complexité. couplage lâche , un objectif architectural très important peut être atteint tranquillement. Un autre objectif architectural important, le séparation des préoccupations peut être atteint beaucoup mieux que les usines.

alors que les usines peuvent être adaptées à de petites applications, les grandes usines seraient mieux de choisir DI plutôt que les usines.

1
répondu Anand Vemula 2017-04-28 08:24:19
la source

la plupart des réponses ici expliquent la différence conceptuelle et les détails de mise en œuvre des deux. Toutefois, je n'ai pas pu trouver d'explications sur les différences d'application entre L'OMI et L'OP. Permettez-moi donc de rouvrir ce sujet...

une fois quelqu'un m'a dit que c'est la façon dont vous l'utilisez qui fait une différence!

exactement. Dans 90% des cas, vous pouvez obtenir la référence de l'objet en utilisant L'usine ou DI et d'habitude, on finit avec ces derniers. Dans un autre 10% des cas, l'utilisation de L'usine est seulement voie correcte . Ces cas incluent l'obtention d'objets par variable à des paramètres d'exécution. Comme ceci:

IWebClient client = factoryWithCache.GetWebClient(url: "stackoverflow.com",
        useCookies: false, connectionTimeout: 120);

dans ce cas, il n'est pas possible d'obtenir client de L'AI (ou du moins il faut faire un détour). Ainsi, comme règle générale pour prendre une décision: si une dépendance peut être obtenue sans n'importe quels paramètres calculés alors DI est préférable, sinon utiliser Usine.

1
répondu neleus 2017-11-21 13:35:51
la source

avec une usine, vous pouvez grouper les interfaces connexes, donc si les paramètres passés peuvent être groupés dans une usine, alors c'est aussi une bonne solution pour constructor overinjection regardez ce code *):

public AddressModelFactory(IAddressAttributeService addressAttributeService,
        IAddressAttributeParser addressAttributeParser,
        ILocalizationService localizationService,
        IStateProvinceService stateProvinceService,
        IAddressAttributeFormatter addressAttributeFormatter)
    {
        this._addressAttributeService = addressAttributeService;
        this._addressAttributeParser = addressAttributeParser;
        this._localizationService = localizationService;
        this._stateProvinceService = stateProvinceService;
        this._addressAttributeFormatter = addressAttributeFormatter;
    }

regardez le constructeur, vous n'avez qu'à passer le IAddressModelFactory là, donc moins de paramètres *):

 public CustomerController(IAddressModelFactory addressModelFactory,
        ICustomerModelFactory customerModelFactory,
        IAuthenticationService authenticationService,
        DateTimeSettings dateTimeSettings,
        TaxSettings taxSettings,
        ILocalizationService localizationService,
        IWorkContext workContext,
        IStoreContext storeContext,
        ICustomerService customerService,
        ICustomerAttributeParser customerAttributeParser,
        ICustomerAttributeService customerAttributeService,
        IGenericAttributeService genericAttributeService,
        ICustomerRegistrationService customerRegistrationService,
        ITaxService taxService,
        CustomerSettings customerSettings,
        AddressSettings addressSettings,...

vous voyez dans CustomerController beaucoup de paramètres passés, Oui vous pouvez voir cela comme constructor overinjection mais c'est comment fonctionne DI. Et pas de rien ne cloche avec le CustomerController .

*) Code est de nopCommerce.

1
répondu Herman Van Der Blom 2017-11-28 17:51:04
la source

en termes simples, la méthode de L'Injection de dépendance par rapport à la méthode de L'usine implique le mécanisme push par rapport au mécanisme pull respectivement.

avec mécanisme de traction: la classe dépend indirectement de la méthode de L'usine qui, à son tour, dépend de classes concrètes.

avec mécanisme Push: le composant Root peut être configuré avec tous les composants dépendants en un seul endroit et favorise ainsi une maintenance élevée et un accouplement lâche.

avec la méthode de L'usine la responsabilité incombe toujours à la classe (bien qu'indirectement) de créer un nouvel objet où comme avec l'injection de dépendance cette responsabilité est externalisée (au prix d'une fuite de l'abstraction cependant)

0
répondu Rahul Agarwal 2018-02-13 10:47:48
la source

je pense que ce sont orthogonaux et peuvent être utilisés ensemble. Permettez-moi de vous montrer un exemple que j'ai récemment rencontré au travail:

nous utilisions le Spring framework en Java pour DI. Une classe singleton ( Parent ) devait instancier de nouveaux objets d'une autre classe ( Child ), et ceux-ci avaient des collaborateurs complexes:

@Component
class Parent {
    // ...
    @Autowired
    Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    void method(int p) {
        Child c = new Child(dep1, dep2, ..., depN, p);
        // ...
    }
}

dans cet exemple, Parent doit recevoir DepX instances seulement pour les passer à la Child constructeur. Problèmes avec ceci:

  1. Parent a plus de connaissances de Child qu'il ne devrait
  2. Parent a plus de collaborateurs qu'il ne devrait
  3. ajouter des dépendances à Child implique de changer Parent

C'est alors que j'ai réalisé qu'un Factory conviendrait parfaitement ici:

  1. il cache tout sauf le vrai paramètres de la classe Child , vus par Parent
  2. il encapsule la connaissance de créer un Child , qui peut être centralisé dans la configuration DI.

c'est la classe simplifiée Parent et la classe ChildFactory :

@Component
class Parent {
    // ...
    @Autowired
    Parent(ChildFactory childFactory) {
        this.childFactory = childFactory;
    }

    void method(int p) {
        Child c = childFactory.newChild(p);
        // ...
    }
}

@Component
class ChildFactory {
    // ...
    @Autowired
    Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
        this.dep1 = dep1;
        this.dep2 = dep2;
        // ...
        this.depN = depN;
    }

    Child newChild(int p) {
        return new Child(dep1, dep2, ..., depN, p);
    }
}
0
répondu Martín Coll 2018-04-16 23:47:19
la source

j'utilise les deux pour créer une Inversion de stratégie de contrôle avec plus de lisibilité pour les développeurs qui ont besoin de le maintenir après moi.

j'utilise une usine pour créer mes différents objets calques (Business, accès aux données).

ICarBusiness carBusiness = BusinessFactory.CreateCarBusiness();

un autre développeur le verra et lors de la création d'un objet Business Layer il regarde dans BusinessFactory et Intellisense donne au développeur toutes les couches Business possibles à créer. Ne doit pas jouer le jeu, Trouver L'Interface que je veux créer.

cette structure est déjà une Inversion de commande. Je ne suis plus responsable de la création de l'objet spécifique. Mais vous devez tout de même vous assurer de L'Injection de dépendances pour être en mesure de changer les choses facilement. Créer votre propre Injection de dépendance personnalisée est ridicule, donc J'utilise L'Unité. Dans le CreateCarBusiness() je demande L'unité pour déterminer quelle classe appartient à ceci et c'est la vie.

So ma structure D'Injection code de dépendance D'usine est:

public static class BusinessFactory
{
    public static ICarBusiness CreateCarBusiness()
    {
       return Container.Resolve<ICarBusiness>();
    }
}

maintenant j'ai le bénéfice des deux. Mon code est aussi plus lisible pour les autres développeurs que pour les scopes de mes objets que j'utilise, au lieu de L'Injection de dépendance au constructeur qui dit simplement que chaque objet est disponible lorsque la classe est créée.

Je l'utilise pour modifier l'accès aux données de ma base de données à une couche d'accès aux données codées personnalisée lorsque je crée des Tests unitaires. Je ne veux pas que les Tests de mon unité communiquer avec des bases de données, serveurs web, serveurs de messagerie, etc. Ils doivent tester ma couche affaires parce que c'est là que se trouve l'intelligence.

0
répondu Michel Bakker 2018-06-25 23:49:38
la source

L'utilisation de l'injection de dépendance est beaucoup mieux à mon avis si vous êtes: 1. déployer votre code dans une petite partition, parce qu'il fonctionne bien dans le découplage d'un gros code. 2. la testabilité est l'un des cas que DI peut utiliser car vous pouvez vous moquer facilement des objets non découplés. avec l'utilisation d'interfaces, vous pouvez facilement simuler et tester chaque objet. 3. vous pouvez réviser simultanément chaque partie du programme sans avoir besoin de coder l'autre partie depuis son découplage lâche.

-2
répondu Adrian 2014-12-22 22:21:33
la source