103 votes

Quels sont les avantages des conteneurs d'injection de dépendance?

Je comprends les avantages de l'injection de dépendance elle-même. Prenons le Printemps par exemple. Je comprends aussi les avantages de Printemps d'autres featureslike AOP, aides de différents types, etc. Je me demandais simplement, quels sont les avantages de XML de configuration, comme par exemple:

<bean id="Mary" class="foo.bar.Female">
  <property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
  <property name="girlfriend" ref="Mary"/>
</bean>

par rapport à plain old java le code tel que:

Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);

ce qui est plus facile à déboguer, compiler temps vérifié et peut être comprise par quelqu'un qui ne connaît que java. Alors, quel est le but principal d'une infrastructure d'injection de dépendance? (ou un morceau de code qui montre ses avantages.)


Mise à JOUR:
En cas de

IService myService;// ...
public void doSomething() {  
  myService.fetchData();
}

Comment peut-Cio cadre de deviner que la mise en œuvre de myService je veux être injecté si il n'y a plus d'un? Si il y a une seule mise en œuvre de l'interface donnée, et je la laisse conteneur IoC automatiquement décider de les utiliser, il sera cassé après une deuxième mise en œuvre apparaît. Et si il est intentionnellement seule possible la mise en œuvre d'une interface, alors vous n'avez pas besoin de se l'injecter.

Il serait vraiment intéressant de voir un petit morceau de la configuration du Cio qui montre les bénéfices. J'ai été en utilisant le Printemps pour un certain temps et je ne peux pas fournir un tel exemple. Et je peux montrer des lignes simples qui démontrent les avantages de la mise en veille prolongée, la dsr, et d'autres cadres que j'utilise.


Mise à JOUR 2:
Je me rends compte que la Coi de configuration peut être changée sans avoir à recompiler. Est-ce vraiment une bonne idée? Je peux comprendre quand quelqu'un veut changer DB informations d'identification sans recompiler - il est peut-être pas développeur. Dans votre pratique, comment souvent quelqu'un d'autre que développeur changements Cio de configuration? Je pense que pour les développeurs, il n'y a aucun effort pour recompiler la classe particulière au lieu de changer de configuration. Et pour les non-développeurs, vous auriez probablement eu envie de rendre sa vie plus facile et de fournir un peu plus simple fichier de configuration.


Mise à JOUR 3:

Configuration externe de la cartographie entre les interfaces et leurs implémentations concrètes

Quel est si bon en rendant extenal? Vous ne faites pas tout votre code externe, alors vous avez certainement peut - il suffit de le placer dans ClassName.java.txt fichier, lire et compiler manuellement à la volée - wow, vous éviter de recompiler. Pourquoi devrait-compilation-elle être évitée?!

Vous enregistrez le codage du temps parce que vous fournir des mappages de manière déclarative, non pas dans un code de procédure

Je comprends que, parfois, approche déclarative permet de gagner du temps. Par exemple, je déclare qu'une seule fois un mappage entre un haricot de propriété et d'une base de colonne et hibernate utilise cette cartographie pendant le chargement, la sauvegarde, la construction de SQL basé sur HSQL, etc. C'est là que l'approche déclarative de travaux. En cas de Printemps (dans mon exemple), la déclaration n'avait plus de lignes et avait la même expressivité que code correspondant. Si il y a un exemple lorsque la déclaration est plus court que le code - je voudrais le voir.

L'Inversion de Contrôle principe permet de faciliter les tests unitaires parce que vous pouvez remplacer les mises en production avec de faux (comme le remplacement de la base de données SQL avec une mémoire de l'un)

Je ne comprends d'inversion de contrôle (je préfère l'appeler la conception motif évoqué ici que l'Injection de Dépendance, parce que le Cio est plus général: il existe de nombreux types de contrôle, et nous sommes en inversant seulement l'un d'eux - le contrôle de l'initialisation). J'ai été demander pourquoi quelqu'un aurait besoin d'autre chose que d'un langage de programmation. Je ne peut certainement remplacer les mises en production avec de faux à l'aide de code. Et ce code permettra d'exprimer la même chose que de la configuration, il suffit d'initialiser les champs avec des fausses valeurs.

mary = new FakeFemale();

Je ne comprends avantages de la DI. Je ne comprends pas quels sont les avantages ajoutés par XML externe configuration par rapport à la configuration de code qui fait la même chose. Je ne pense pas que la compilation doit être évitée - je compiler tous les jours et je suis encore en vie. Je pense que la configuration de DI est le mauvais exemple de l'approche déclarative. La déclaration peut être utile s'est déclaré une fois ET est utilisée plusieurs fois de différentes façons - comme hibernate cfg, où la correspondance entre la fève de la propriété et de la colonne DB est utilisé pour l'enregistrement, de chargement, de la construction des requêtes de recherche, etc. Printemps DI configuration peut être facilement traduit à la configuration de code, comme dans le début de cette question, ne peut-il pas? Et il est utilisé uniquement pour l'initialisation du bean, n'est-ce pas? Ce qui signifie une approche déclarative ne pas ajouter quoi que ce soit ici, n'est ce pas?

Lorsque je déclare hibernate mapping, je viens de donner hibernate quelques informations, et il travaille en se fondant sur elle - je ne pas lui dire quoi faire. En cas de printemps, ma dit la déclaration de printemps exactement wht à faire, alors pourquoi le déclarer, pourquoi ne pas le faire?


DERNIÈRE MISE À JOUR:
Les gars, beaucoup de réponses sont de me dire à propos de l'injection de dépendance, dont je SAIS qu'elle EST BONNE. La question est sur le but de DI configuration, au lieu de l'initialisation de code - j'ai tendance à penser que l'initialisation du code est plus court et plus clair. La seule réponse que j'ai eu jusqu'à présent à ma question, c'est qu'il évite de recompiler, lorsque les changements de configuration. Je suppose que je devrais poster une autre question, parce que c'est un grand secret pour moi, raison pour laquelle la compilation doit être évitée dans ce cas.

14voto

Kevin S. Points 610

L'injection de dépendance est un style de codage qui a ses racines dans l'observation que l'objet de la délégation est généralement plus utile motif de conception que l'héritage d'objet (c'est à dire, l'objet a-une relation est plus utile que l'objet est une relation). Un autre ingrédient est nécessaire cependant pour DI de travail, celui de la création d'interfaces d'objets. La combinaison de ces deux puissants patrons de conception, les ingénieurs en logiciel rapidement rendu compte qu'ils pouvaient créer souple faiblement couplé code et ainsi, le concept de l'Injection de Dépendance est né. Cependant, il n'était pas jusqu'à ce que l'objet de la réflexion est devenu disponible dans certaines haut niveau de langues que DI a vraiment décollé. La réflexion composant de base pour la plupart des DI systèmes d'aujourd'hui, parce que la vraiment cool aspects de DI nécessitent la capacité de programmation pour sélectionner les objets et de les configurer et de les injecter dans d'autres objets à l'aide d'un système externe et indépendant des objets eux-mêmes.

Une langue doit fournir un bon support pour les deux normal de la programmation Orientée Objet, les techniques ainsi que le soutien pour objet d'interfaces et de l'objet de la réflexion (par exemple Java et C#). Alors que vous pouvez créer des programmes à l'aide de DI modèles en C++ de systèmes de son manque de réflexion d'un soutien dans la langue appropriée, il l'empêche de soutenir les serveurs d'applications et d'autres DI plates-formes et donc les limites de l'expressivité de la DI modèles.

Les points forts d'un système construit à l'aide de DI modèles:

  1. DI code est beaucoup plus facile de les réutiliser comme le "dépendait' fonctionnalité est extrapolé en bien définie des interfaces permettant de séparer des objets dont la configuration est gérée par une application appropriée plate-forme pour être branché sur d'autres objets à volonté.
  2. DI code est beaucoup plus facile à tester. La fonctionnalité exprimé par l'objet peut être testé dans une boîte noire par la construction de "mock" objets implémentant les interfaces prévu par la logique de l'application.
  3. DI code est plus souple. Il est naturellement faiblement couplé code -- à l'extrême. Cela permet au programmeur de choisir comment sont connectés les objets basé exclusivement sur leurs interfaces nécessaires à une extrémité, et leur a exprimé des interfaces sur l'autre.
  4. Externe (Xml), configuration de DI objets signifie que d'autres peuvent personnaliser votre code dans des directions non prévues.
  5. Configuration externe est également une séparation des préoccupations de modèle à tous les problèmes de l'initialisation de l'objet et de l'objet de l'interdépendance de gestion peuvent être traitées par le serveur d'application.
  6. Notez que la configuration externe n'est pas nécessaire pour utiliser le DI motif, pour la simple interconnexions un petit objet builder est souvent suffisante. Il est nécessaire de trouver un compromis au niveau de la flexibilité entre les deux. Un constructeur d'objet n'est pas aussi souple qu'une option comme visible de l'extérieur fichier de configuration. Le développeur de la DI système doit soupeser les avantages de la flexibilité sur la commodité, en prenant soin de la petite échelle, à grain fin, de contrôle sur la construction de l'objet comme l'a exprimé dans un fichier de configuration peut augmenter la confusion et les coûts de maintenance bas de la ligne.

Certainement DI code semble de plus en plus lourde, les inconvénients d'avoir tous ces fichiers XML de configuration des objets à être injecté dans d'autres objets apparaît difficile. C'est, cependant, le point de DI systèmes. Votre capacité de mélanger et assortir code des objets comme une série de paramètres de configuration vous permet de construire des systèmes complexes à l'aide de la 3e partie du code avec un minimum de codage de votre part.

L'exemple fourni dans la question simple touche sur la surface de la puissance expressive qu'un bien reflété DI objet de la bibliothèque peut fournir. Avec un peu de pratique et beaucoup d'auto-discipline plus DI praticiens constatent qu'ils peuvent construire des systèmes qui ont 100% de couverture de test de code de l'application. Ce un seul point est extraordinaire. Ce n'est pas à 100% de la couverture de test d'une petite application de quelques centaines de lignes de code, mais 100% de couverture de test d'applications comprenant des centaines de milliers de lignes de code. Je suis à une perte de pouvoir décrire tout autre motif de conception qui fournit ce niveau de la testabilité.

Vous avez raison en ce sens que l'application d'un simple 10s de lignes de code est plus facile à comprendre que plusieurs objets en plus d'une série de fichiers de configuration XML. Cependant, comme avec le plus puissant des modèles de conception, les gains ne sont trouvés que vous continuez à ajouter de nouvelles fonctionnalités au système.

En bref, à grande échelle DI en fonction des applications sont à la fois plus facile à déboguer et plus facile à comprendre. Tandis que la configuration Xml n'est pas "le temps de compilation coché la case" tous les services d'applications que cet auteur est conscient de la volonté de fournir le développeur avec des messages d'erreur si elles tentent d'injecter un objet ayant une interface incompatible dans un autre objet. Et en plus de fournir un "check" fonctionnalité qui englobe tous les objets connus configurations. Ceci est facilement et rapidement fait en vérifiant que l'être injecté Un objet implémente l'interface requise par l'objet B pour tous configurés objet d'injections.

7voto

Mike Stone Points 21293

C'est un peu une question piège, mais j'ai tendance à être d'accord que d'énormes quantités de configuration xml n'a pas vraiment beaucoup d'avantages. J'aime mes applications comme la lumière sur les dépendances que possible, y compris le costaud des cadres.

Ils simplifient le code beaucoup de temps, mais ils ont aussi une surcharge lors de la complexité qui rend le suivi des problèmes plutôt difficile (je l'ai vu de tels problèmes, d'une part, et le droit de Java, je serais beaucoup plus à l'aise avec).

Je suppose que ça dépend du style un peu, et ce que vous êtes à l'aise avec... vous aimez voler votre propre solution et ont l'avantage de le savoir à l'intérieur, ou de la banque sur les solutions existantes qui peut s'avérer difficile lorsque la configuration n'est pas juste? C'est tout un équilibre.

Cependant, XML de configuration est un peu bête noire de la mienne... j'ai essayer de l'éviter à tout prix.

5voto

Bill K Points 32115

Tout moment vous pouvez modifier votre code pour les données que vous êtes de faire un pas dans la bonne direction.

Codage rien que des données signifie que votre code lui-même est plus général et réutilisables. Cela signifie également que vos données peuvent être spécifiés dans une langue qu'il s'adapte exactement.

Aussi, un fichier XML peut être lu dans une interface graphique, ou un autre outil et de le manipuler facilement et de façon pragmatique. Comment voudriez-vous faire cela avec l'exemple de code?

Je suis constamment à l'affacturage les choses la plupart des gens serait la mise en œuvre du code dans les données, il fait ce code est à gauche BEAUCOUP plus propre. Je trouve inconcevable que les gens vont créer un menu dans le code plutôt que comme des données, il devrait être évident que le faire dans le code est tout simplement faux.

3voto

MetroidFan2002 Points 11413

La raison de l'utilisation d'un conteneur d'injection de dépendances sont que vous n'avez pas à avoir un milliard de propriétés pré-configuré dans votre code qui sont tout simplement des getters et setters. Avez-vous vraiment envie de coder en dur tous ceux avec new X()? Bien sûr, vous pouvez avoir un défaut, mais le conteneur d'injection de dépendances permet la création de singletons qui est extrêmement simple et permet de vous concentrer sur les détails du code, pas les diverses tâches d'initialisation.

Par exemple, le Printemps vous permet de mettre en œuvre les InitializingBean interface et ajouter un afterPropertiesSet méthode (vous pouvez aussi spécifier un "init-method" pour éviter les problèmes de couplage votre code de Printemps). Ces méthodes vous permettent de vous assurer que toute l'interface spécifiée comme un champ dans votre instance de classe est correctement configuré au démarrage, et puis vous n'avez plus à null-vérifiez votre getters et les setters (en supposant que vous ne permettre à votre singletons de rester thread-safe).

En outre, il est beaucoup plus facile de faire de complexe d'initialisation avec un conteneur d'injection de dépendances au lieu de les faire vous-même. Par exemple, je l'aide avec l'aide de XFire (pas CeltiXFire, nous n'utilisons Java 1.4). L'application utilisée Printemps, mais c'est malheureusement utilisé XFire est services.xml configuration du mécanisme. Lorsqu'une Collection d'éléments nécessaires à déclarer qu'il y avait ZÉRO ou plus occurrences au lieu d'UNE ou de plusieurs instances, j'ai eu à remplacer certains des XFire code pour ce service particulier.

Il y a certaines XFire des valeurs par défaut définies dans ses beans Spring schéma. Donc, si nous étions à l'aide de Printemps pour configurer les services, les haricots ont été utilisés. Au lieu de cela, ce qui s'est passé c'est que j'avais à fournir une instance d'une classe spécifique dans le services.xml fichier au lieu d'utiliser les haricots. Pour ce faire, j'avais besoin de fournir le constructeur et définir des références déclarées dans le XFire de configuration. Le vrai changement, que j'avais besoin de faire fallu que j'surcharger une classe unique.

Mais, grâce à la services.xml fichier, j'ai eu à la création de quatre nouvelles classes, réglage par défaut en fonction de leurs valeurs par défaut dans la configuration Spring fichiers dans leurs constructeurs. Si nous avions été en mesure d'utiliser la configuration Spring, j'aurais juste a déclaré:

<bean id="base" parent="RootXFireBean">
    <property name="secondProperty" ref="secondBean" />
</bean>

<bean id="secondBean" parent="secondaryXFireBean">
    <property name="firstProperty" ref="thirdBean" />
</bean>

<bean id="thirdBean" parent="thirdXFireBean">
    <property name="secondProperty" ref="myNewBean" />
</bean>

<bean id="myNewBean" class="WowItsActuallyTheCodeThatChanged" />

Au lieu de cela, il ressemblait plutôt à ça:

public class TheFirstPointlessClass extends SomeXFireClass {
    public TheFirstPointlessClass() {
        setFirstProperty(new TheSecondPointlessClass());
        setSecondProperty(new TheThingThatWasHereBefore());
    }
}

public class TheSecondPointlessClass extends YetAnotherXFireClass {
    public TheSecondPointlessClass() {
        setFirstProperty(TheThirdPointlessClass());
    }
}

public class TheThirdPointlessClass extends GeeAnotherXFireClass {
    public TheThirdPointlessClass() {
        setFirstProperty(new AnotherThingThatWasHereBefore());
        setSecondProperty(new WowItsActuallyTheCodeThatChanged());
    }
}

public class WowItsActuallyTheCodeThatChanged extends TheXFireClassIActuallyCareAbout {
    public WowItsActuallyTheCodeThatChanged() {
    }

    public overrideTheMethod(Object[] arguments) {
        //Do overridden stuff
    }
}

Ainsi, le résultat net est que les quatre autres, pour la plupart inutiles classes Java devait être ajouté à la base de code pour obtenir l'effet qu'une classe supplémentaire et une simple dépendance contenant des renseignements obtenus. Ce n'est pas "l'exception qui confirme la règle", c'EST la règle...de manutention des bizarreries dans le code est beaucoup plus propre lorsque les propriétés sont déjà fournis dans un conteneur d'injection de dépendances et vous êtes tout simplement en changer pour s'adapter à une situation particulière, ce qui arrive le plus souvent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X