L'injection de dépendance à la main est-elle une meilleure alternative à la composition et au polymorphisme?

13

Tout d'abord, je suis un programmeur d'entrée de gamme; En fait, je termine un diplôme AS avec un projet final de capstone au cours de l'été. Dans mon nouveau travail, quand je n'ai pas de projet à faire (ils attendent de remplir l'équipe avec plus de nouvelles embauches), on m'a donné des livres à lire et à apprendre pendant que j'attends - certains manuels, d'autres pas tellement (comme Code Complete). Après avoir parcouru ces livres, je me suis tourné vers Internet pour en apprendre autant que possible, et j'ai commencé à en apprendre davantage sur SOLID et DI (nous avons parlé du principe de substitution de Liskov, mais pas beaucoup d'autres idées SOLID). Donc, comme je l'ai appris, je me suis assis pour faire mieux et j'ai commencé à écrire du code pour utiliser DI à la main (il n'y a pas de framework DI sur les ordinateurs de développement).

La chose est, comme je le fais, je remarque que cela semble familier ... et il semble que cela ressemble beaucoup au travail que j'ai fait dans le passé en utilisant la composition de classes abstraites en utilisant le polymorphisme. Me manque-t-il une image plus grande ici? Y a-t-il quelque chose à propos de DI (au moins à la main) qui va au-delà? Je comprends la possibilité d'avoir des configurations non dans le code de certains frameworks DI ayant de grands avantages en ce qui concerne la modification des choses sans avoir à recompiler, mais en le faisant à la main, je ne suis pas sûr que ce soit différent de celui indiqué ci-dessus ... Un aperçu de cela serait très utile!

Drake Clarris
la source

Réponses:

21

L'idée fondamentale dans DI est simplement de pousser des dépendances dans des objets, plutôt que de les laisser tirer des dépendances de l'extérieur. Cela a également été appelé «inversion de contrôle» plus tôt. Cela permet de mieux contrôler les dépendances et, enfin et surtout, d'écrire du code facile à tester.

Les infrastructures DI ne s'appuient que sur cette idée et automatisent (en partie) la partie souvent fastidieuse du câblage des dépendances des objets. Sinon, cela peut nécessiter une quantité importante de code dans un projet plus important lorsqu'il est fait à la main.

Pour définir les dépendances, outre les fichiers de configuration externes, il est également possible d'utiliser des annotations de code de nos jours, par exemple dans des langages comme Java et C #. Celles-ci peuvent apporter le meilleur des deux mondes: câbler les dépendances dans un style déclaratif, mais directement dans le code lui-même, où il appartient logiquement. Pour moi, la possibilité de changer les dépendances sans avoir à recompiler n'est pas si précieuse, car cela se fait rarement dans la vie réelle (à l'exception de certains cas spéciaux), mais introduit une séparation souvent artificielle des dépendances des classes et des objets définis dans le code .

Pour revenir à votre question de titre, DI n'est pas une alternative à la composition ni au polymorphisme; après tout, cela est rendu possible par ces deux-là.

Péter Török
la source
1
L'injection de dépendance (DI) est une forme d'inversion de contrôle (IoC).
Matthew Flynn
@MatthewFlynn, en effet. Pour référence: martinfowler.com/articles/injection.html
Péter Török
1
C'EST ma référence. Il parle des nouveaux "conteneurs légers" qui font l'inversion du contrôle, ce qui était déjà courant car les écouteurs d'événements UI étaient une forme d'IoC. Il surnomme la liaison d'objet que Spring et d'autres conteneurs IoC font comme injection de dépendance pour le différencier de l'autre forme d'inversion de contrôle.
Matthew Flynn
Oups - j'ai raté le "en effet". Je pensais que tu me contredisais ... Désolé.
Matthew Flynn
Votre dernier paragraphe me fait me sentir un peu mieux; tout le temps que je travaillais sur mon petit projet d'apprentissage, je n'arrêtais pas de me dire "ça ressemble à du polymorphisme ..". Malheureusement, le .Net et le c # dans mon travail sont horriblement obsolètes, mais à y regarder, Unity est-il le framework c # intégré dont vous parlez?
Drake Clarris
22

Le meilleur article que j'ai jamais lu sur le sujet était celui de James Shore . Je fais du " DI à la main " depuis des lustres, dans le cadre de l'abstraction et du polymorphisme. Donc, après que je suis entré dans le monde professionnel et que je n'arrêtais pas d'entendre parler de ce terme, j'avais un grand décalage entre ce que je pensais que le mot devrait signifier et ce qu'il signifie réellement:

"Injection de dépendance" est un terme de 25 dollars pour un concept de 5 cents.

Ça vient du post de Shore, qui m'a tout éclairci. Par exemple:

Donné

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

Au lieu d'écrire:

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

Vous écrivez quelque chose comme ceci:

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

Et cela empêche l' Carinstance d'avoir à gérer des Enginedétails spécifiques . Une voiture a juste besoin d'un moteur, peu importe laquelle tant qu'elle met en œuvre la fonctionnalité de base du moteur. Autrement dit, votre Carclasse n'est pas liée à une dépendance d'implémentation spécifique; il est "injecté" ailleurs, potentiellement lors de l'exécution.

Cet exemple spécifique de voiture utilise le sous-type de DI appelé "injection de constructeur", ce qui signifie simplement que la dépendance a été transmise comme argument de constructeur. Vous pouvez également utiliser une setEngine(Engine a)méthode pour "Setter Injection", et ainsi de suite, mais ces sous-types me semblent pédants.

Un peu plus loin, cependant, de nombreux frameworks DI fournissent le passe-partout pour connecter un tas de ces choses référencées de manière plus abstraite les unes aux autres.

C'est ça.

pseudo
la source
0

Je ne suis pas un expert car je n'ai commencé à utiliser DI qu'au cours des dernières années, mais quelques-uns des thèmes / fonctionnalités utiles des conteneurs DI que j'ai remarqués sont (que je ne considère pas comme des produits de composition / polymorphisme (mais je peux être corrigé à ce sujet):

  • hub central de création d'objets
  • fournir des singletons par thread
  • techniques orientées vers l'aspect telles que l'interception
Aaron Anodide
la source
0

Outre DI, il existe une configuration de composition de classe dans l'application racine (au lieu de la configuration à l'aide de xml). Il n'y a pas besoin de framework DI ou IoC, même s'ils peuvent ranger la configuration de composition de classe, en particulier pour les grands projets. Cela est dû au fait que le framework DI est normalement fourni avec un conteneur qui implémente des fonctionnalités supplémentaires, telles que le câblage automatique, qui aident à configurer la composition des classes. Vous pouvez lire mon entrée de blog pour extraire ma compréhension de ce sujet.

kusnaditjung tjung
la source