Introduction à l'injection de dépendances

a marqué ce sujet comme résolu.

Bonjour à tous,

J'ai commencé (il y a 5 mois) la rédaction d'un tutoriel dont l'intitulé est Introduction à l'injection de dépendances en Java.

J'aimerai obtenir un maximum de retour sur celui-ci, sur le fond ainsi que sur la forme, afin de proposer en validation un texte de qualité.

Si vous êtes intéressé, cliquez ci-dessous

Merci d'avance pour votre aide

+0 -0

Juste à propos du titre : même si le terme Java apparaît dans les tags, on ne comprend pas trop au premier abord de quoi tu parles. Personnellement, je pensais que tu mentionnerais des trucs du genre les gestionnaires de paquets. ^^

+0 -0

Juste à propos du titre : même si le terme Java apparaît dans les tags, on ne comprend pas trop au premier abord de quoi tu parles. Personnellement, je pensais que tu mentionnerais des trucs du genre les gestionnaires de paquets. ^^

Vayel

Je ne comprends pas trop le lien entre un gestionnaire de paquets et l'injection de dépendances mais tu proposes que j'indique le terme Java dans le titre du tutoriel ? Quelque chose comme : Introduction à l'injection de dépendances en Java.

Je pense qu'à la lecture seule du titre, il a cru que tu parlais de dépendances entre paquets/projets/whatever. En plus de ça, tu parles de Maven dans l'intro comme d'un « gestionnaire de dépendances » C'est confusant par rapport au titre.

Pour ce qui est du tuto, je suis un peu resté sur ma faim, honnêtement. C'est pas le contenu auquel je m'attendais. Je trouve que tu sautes trop vite sur l'outil et que tu passes la théorie. Du coup, à mes yeux, le titre est trompeur. Ça aurait dû être « L'injection de dépendances avec Google Guice » ou quelque chose comme ça.

+0 -0

Je pense qu'à la lecture seule du titre, il a cru que tu parlais de dépendances entre paquets/projets/whatever.

C'est ça. =)

Vayel

Ah oui, d'accord. Donc il faut déjà éclaircir le titre du tutoriel à ce sujet.

Pour ce qui est du tuto, je suis un peu resté sur ma faim, honnêtement. C'est pas le contenu auquel je m'attendais. Je trouve que tu sautes trop vite sur l'outil et que tu passes la théorie. Du coup, à mes yeux, le titre est trompeur. Ça aurait dû être « L'injection de dépendances avec Google Guice » ou quelque chose comme ça.

lethom

Mon avis est qu'un exemple vaut mieux qu'un long discours. Par contre, tu voudrais peut-être que j'etoffe un peu plus les 2 premières parties ?

Je pense qu'à la lecture seule du titre, il a cru que tu parlais de dépendances entre paquets/projets/whatever.

C'est ça. =)

Vayel

A ce compte là, le tutoriel parlerait de gestion de dépendances.

L'injection de dépendances c'est vraiment ce qui est couvert par Andr0 dans son tutoriel (dans la version précédente que j'avais lue en tout cas).

L'injection de dépendances est un pattern, qu'on retrouve assez fréquemment dans les langages objets voire en Javascript. Je ne suis pas sûr qu'il faille revenir sur ce point dans le cours d'Andr0, en tout cas, pas sur le titre.

Un cours sur la gestion de dépendances (Maven, Gradle, Pip, Gem, RequireJS, …) serait intéressant également, mais ce n'est pas l'objet d'un tel cours.

+0 -0

L'injection de dépendances c'est vraiment ce qui est couvert par Andr0 dans son tutoriel (dans la version précédente que j'avais lue en tout cas).

L'injection de dépendances est un pattern, qu'on retrouve assez fréquemment dans les langages objets voire en Javascript. Je ne suis pas sûr qu'il faille revenir sur ce point dans le cours d'Andr0, en tout cas, pas sur le titre.

J'aurais pu expliquer l'injection de dépendances sans bibliothèque mais cela ne me semblait pas pertinent puisque les bibliothèques actuelles font très bien le travail.

Sinon, la nouvelle version n'est qu'une modification du titre du tutoriel pour rajouter "en Java" à la fin. Cela permettra d'éviter toute confusion sur son sujet.

Un cours sur la gestion de dépendances (Maven, Gradle, Pip, Gem, RequireJS, …) serait intéressant également, mais ce n'est pas l'objet d'un tel cours.

Ca fait un moment que j'aimerais rédiger un tutoriel Maven ou Gradle mais cela prendrait un big tuto entier. Je préfère le format des mini tutoriels pour éviter de se décourager en cours de route.

En fait, mon propos peut se résumer ainsi : je trouve le titre un peu mensonger. Ça n'engage que moi, mais je vais développer tout de même. Libre à toi d'en tenir compte ou non.

En soit, ton cours n'est pas tant une introduction à l'injection de dépendances. À mes yeux, ça aurait été plus le cas si ton cours avait été agnostique au niveau des langages et des bibliothèques. Je m'attendais à retrouver le pattern, justement. En soit, quand tu dis :

J'aurais pu expliquer l'injection de dépendances sans bibliothèque mais cela ne me semblait pas pertinent puisque les bibliothèques actuelles font très bien le travail.

C'est vrai, sans aucun doute. Mais dans ce cas, ton cours est plus un exemple d'injection de dépendances. Voilà voilà. C'est sans doute du pinaillage et encore une fois, ça n'engage que moi.

+0 -0

Non, ton avis est très intéressant. Je n'avais pas envisagé les choses ainsi quand j'ai rédigé mon tutoriel mais la confusion est permise, tout autant que la déception liée.

Donc, j'ai changé le titre du tutoriel pour spécifier que j'explique l'injection de dépendances dans le cadre du Java. C'est une première indication pour mentionner que ce n'est pas le pattern qui est expliqué (indépendant du langage) mais bien une implémentation à travers ce langage.

En y réfléchissant, je pense que le pattern mériterait un tutoriel à part entière et ne rentre pas dans le cadre du tutoriel ci-présent puisque, grâce au titre, le futur auteur s'attendra plus à une implémentation qu'au pattern.

Du même avis ? :)

Un truc assez amusant dans le premier exemple :

1
2
3
4
5
6
public class Pizzeria {
    public Pizza make() {
        final PizzaMaker maker = new PizzaMaker();
        return maker.make();
    }
}

C'est qu'en fait, plus que de l'injection de dépendances, c'est de delegate dont il traite directement.

Et du coup (honnêtement) j'ai mélangé un peu les deux en première lecture.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Pizzeria {
    @Delegate PizzaMaker maker
}

class PizzaMaker {
    def make(){
        new Pizza()
    }
}

assert new Pizzeria().make() != null

Ensuite, j'ai du mal (mais c'est peut-être que moi) avec les exemples.

  1. Je pense qu'il faut écrire les commentaires et méthodes en Anglais en fait, je le fais jamais sur mon code, j'imagine que toi non plus, mais pour un tuto je pense qu'il vaudrait mieux le faire (surtout les commentaires). Mais bon c'est un détail

  2. Je connais bien Spring, l'IOC, l'injection de dépendances. Je l'ai souvent utilisée. Mais je ne connais pas Guice et autres bibliothèques modernes. Et du coup j'ai du mal à retrouver des concepts connus.

    2.1. Le conteneur (léger) : c'est qui, c'est quoi ? Qui "détient" les beans créés

    2.2. Pour moi y'a deux "familles" de dépendances injectées : d'une part les singletons (config, handlers, …) d'autre part l'injection à partir d'un contexte. Et là du coup j'ai du mal à retrouver ces deux concepts.

J'ai l'impression que tu raisonnes comme si tout était des singletons, mais j'en suis pas sûr.

En gros, par exemple dans une application MVC (web ou pas), on va avoir des Contrôleurs. Chacun EST un singleton. Ils ont tous des dépendances (qui sont aussi des singletons) et l'injection nous aide à décrire tout ça pour qu'au lancement de l'app tout soit initialisé proprement.

Par contre, certains objets vont être créés en fonction d'un contexte (et ne sont pas des singletons) et dans ce cas, le contexte doit être injecté automatiquement.

Ton cours me laisse imaginer qu'on est dans le second cas mais pourtant, comment dire… Le pizzaMaker n'existe pas en dehors de la Pizzeria. C'est troublant parce que l'injection de dépendances telle que je la connais c'est "Je prends un bean, je l'injecte dans un autre". Là c'est vraiment 100% par construction : "Ce bean est instancié, il a besoin d'une instance d'une autre classe, je crée une nouvelle instance de la classe".

Et c'est là que la notion de conteneur est intéressante pour comprendre tout ça. Quand tu sais que tu disposes d'une "usine" à beans (comme ici) mais que cette usine répertorie les beans qu'elle a créée sous un nom donné (@Component dans Spring) tu sais qu'elle peut aller chercher une instance donnée via son nom pour l'injecter quelque part.

Je sais pas si j'suis clair, j'avoue que je me paume un ptit peu moi-même.

+0 -0

Zut, la validation du tutoriel arrivait à terme et tu remets en cause pas mal de choses. ^^

Je sais pas si j'suis clair, j'avoue que je me paume un ptit peu moi-même.

Oui, ton message est confus mais je vais tenter de distinguer tes différentes interrogations pour y répondre. Tout en sachant que je connais peu Spring.

C'est qu'en fait, plus que de l'injection de dépendances, c'est de delegate dont il traite directement.

Et du coup (honnêtement) j'ai mélangé un peu les deux en première lecture.

En fait, cet exemple est là pour illustrer une dépendance.

Je pense qu'il faut écrire les commentaires et méthodes en Anglais en fait, je le fais jamais sur mon code, j'imagine que toi non plus, mais pour un tuto je pense qu'il vaudrait mieux le faire (surtout les commentaires). Mais bon c'est un détail

Je ne comprends pas. Mon code et mes commentaires sont en anglais. Tu penses à quoi en disant ça ?

Je connais bien Spring, l'IOC, l'injection de dépendances. Je l'ai souvent utilisée. Mais je ne connais pas Guice et autres bibliothèques modernes. Et du coup j'ai du mal à retrouver des concepts connus.

Je crois que la première faute à faire c'est de comparer Spring et Google Guice/Dagger (raison pour laquelle je ne l'aborde pas dans mon tutoriel en plus du fait que je le connais peu). Spring est un conteneur léger disposant de plein de technologies dont Spring IoC. Tous les concepts dans Spring ne se retrouvent pas dans les solutions que je présente dans ce tutoriel qui sont uniquement des frameworks d'injection, ils ne peuvent rien faire d'autres.

J'ai l'impression que tu raisonnes comme si tout était des singletons, mais j'en suis pas sûr.

Non, tout n'est pas singleton. Uniquement les classes d'implémentation que tu annotes @Singleton mais le tutoriel me semblait suffisamment conséquent pour un mini tutoriel. Tu penses que ça serait utile que je le mentionne ?

"Ce bean est instancié, il a besoin d'une instance d'une autre classe, je crée une nouvelle instance de la classe".

On ne parle pas de "bean" avec Guice ou Dagger mais c'est exactement ça.

J'espère que j'ai réussi à éclaircir tes intégrations. Si tu as des choses que tu penses que je devrais expliciter dans le tutoriel pour que cela soit plus clair, n'hésite pas !

Il fallait lire "Français" au lieu d'Anglais… Désolé…

Alors OK, mais le truc que je trouve trompeur dans l'exemple, c'est qu'on imagine qu'un PizzaMaker a "une vie" en dehors de la Pizzeria alors qu'en fait on injecte à la construction de la Pizzeria une instance, dont le scope se limite à la Pizzeria, avec un rapport 1-1.

Et du coup c'est ça qui me trouble un peu, je ne vois pas vraiment l'intérêt de l'injection de dépendance dans ce cas.

Peut-être qu'un truc qui éclairerait complètement ma lanterne serait le cas de figure suivant : un pizzaiolo bosse dans deux pizzerias à la fois.

En gros si c'est pour wrapper un objet dans un autre, honnêtement je saisis pas l'intérêt d'utiliser une lib, tu enlèves une ligne d'un constructeur pour la déplacer dans tout un tas de config/bootstrapping. Et ptet' que c'est là-dessus qu'il faudrait creuser ? (je joue le naïf délibérément)

Tu vois ce que je veux dire ?

+0 -0

Tout à fait. Je commence à comprendre ce qui te chiffonne. J'ai tenté de prendre les exemples les plus simples possibles. Déjà, nous pouvons nous mettre d'accord sur un point : l'injection de dépendances ne serait pas vraiment nécessaire pour les exemples que je donne, ce sont juste des petits exemples très simplistes pour exposer les différents concepts de l'injection avec Guice et Dagger. Rien de plus.

Par contre, je pense que tu extrapoles un peu trop. L'idée n'est pas d'imaginer ce que pourrait faire le pizzaiolo en dehors de la pizzeria. Ca ne nous intéresse pas. L'idée s'est d'expliquer que la classe Pizzeria possède une dépendance vers une autre classe PizzaMaker pour concevoir des Pizza. Si ça te perturbe vraiment, je peux avoir le PizzaMaker directement comme point d'entrée mais est-ce que ça sera vraiment plus clair ?

Pour te donner un exemple de mon usage (que je vais simplifier) dans mes projets, j'ai souvent ce que j'appelle des managers et des daos. Mes managers ont comme responsabilités d'avoir la logique métier de mes ressources (User, Order, etc.) et mes daos ont comme responsabilités de communiquer avec la base de données. Et bien tous mes managers et tous mes daos sont injectables dans les autres managers (bien qu'ils ne sont pas forcément injectés bien sûr).

Est-ce que tu comprends mieux l'utilité ?

Oui oui pour l'utilité t'en fais pas, j'ai utilisé Spring pendant des années, je suis en train de ré-implémenter Jersey sur Vert.x, j'utilise aussi des services, modules, contrôleurs AngularJS donc oui le cas que tu décris ne m'est pas du tout inconnu ^^

Ce que je veux dire c'est que soit :

  • le cours s'adresse à des gens qui connaissent l'injection de dépendance et à ce compte-là il vaut mieux se cantonner à décrire les annotations et ce qu'elles font (si je devais écrire un truc sur Spring, je dirais que tes managers sont des @Component et que dans chacun on retrouve des DAOs @Autowired, et je pourrais presque m'arrêter là)

  • le cours s'adresse à des débutants complets, et à ce compte là l'exemple ne suffit pas, puisque dans ce cas l'injection de dépendance n'a quasiment aucun intérêt.

L'exemple d'AngularJS est frappant d'ailleurs. Tu as un service qui fait des requêtes APIs, tu vas t'en servir dans presque tous tes contrôleurs. Et t'as pas envie d'aller le chercher à chaque fois. T'as envie de déclarer ta dépendance et que le framework s'en occupe.

Ton exemple de managers et DAOs et l'exemple parfait d'injection de dépendances et du coup tu le dis toi-même "tous mes DAOs sont injectables dans n'importe quel manager" => OUI et je pense que c'est ça qu'il est essentiel de faire comprendre à un débutant, sans quoi il risque de ne pas comprendre l'intérêt.

Je me mets à la place d'un débutant : pour initialiser une propriété intrinsèque d'un objet, autant passer par le constructeur. Par contre pour injecter un objet qui a un cycle de vie en dehors de mon objet alors là oui.

(ça revient à l'histoire du pizzaiolo qui bosse dans plein de pizzeria à la fois, peut-être qu'en parlant des recettes ça serait plus illustratif d'ailleurs).

+0 -0
Ce sujet est verrouillé.