[JAVA] Quoi qu'il en soit, résumé de Dagger2

〇Introduction

Dagger2 C'est difficile. Comme l'introduction était difficile, j'ai brièvement résumé la partie d'introduction pour le moment, en utilisant divers sites comme indices. Ce blog utilise @Inject, @Module, @Provide, @Component, Je voudrais écrire le plus clairement possible, jusqu'à injecter des dépendances et des fonctions de commutation. Pour une raison quelconque, j'ai choisi Java cette fois.

〇 Qu'est-ce que Dagger2?

"Cadre de compilation pour l'injection de dépendances" développé par Google Pour faire simple, si vous créez une instance d'une autre classe dans une classe, Puisqu'il devient difficile de tester chaque classe, Basculez vers une méthode appelée injection de dépendances, qui crée une instance au moment de la compilation et l'injecte. Pour faciliter la maintenance et les tests.

〇 URL de référence

・ [Officiel] GitHub https://github.com/google/dagger ・ Guide de l'utilisateur [officiel] https://google.github.io/dagger/users-guide.html ・ Introduction à dagger2 (2.11) extrêmement facile à comprendre ――C'est incroyablement facile à comprendre! https://qiita.com/m-dove/items/767c4bfaeee53caefc4d ・ Je comprends cela (je pense que je comprends)! Dague 2

〇 Programme

・ Liste GitHub

[\ 1 ] Exemple avant d'utiliser Dagger2 [Injection dépendant de l'échantillon en utilisant \ 2 ] @Inject, @Component [Exemple pour changer le contenu de l'injection en utilisant \ 3 ] @Module, @Provide

[1] Échantillon avant d'utiliser Dagger2

Ceci est un exemple simple. Créez une instance de Fortune Machine avec MainActivity. Cela créera une instance de TwiterClient dans le constructeur FortuneMachine. Lorsque vous appelez checkFortune of FortuneMachine, vous tirez au sort une loterie, Publiez sur Twitter avec postData de TwitterClient. (La partie publiée sur Twitter est cassée, il suffit de cracher le journal) Juste au cas où, la chaîne de caractères est également renvoyée à MainActivity.

MainActivity.java


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FortuneMachine fortuneMachine = new FortuneMachine();

        Log.w( "DEBUG_DATA", "result = " + fortuneMachine.checkFortune());
    }
}

FortuneMachine.java


public class FortuneMachine {
    TwiterClient twiterClient;

    String[] fortunes = {"Daikichi","Nakayoshi","Kokichi","Mal","大Mal"};

    public FortuneMachine(){
        //Créer une instance de TwiterClient
        twiterClient = new TwiterClient();
    }

    public String checkFortune(){
        int no = getRandomNo();
        twiterClient.postData(fortunes[no]);
        return fortunes[no];
    }

    public int getRandomNo(){
        Random r = new Random();
        int n = r.nextInt(fortunes.length);

        return n;
    }
}

TwitterClient.java


public class TwiterClient {

    public TwiterClient(){
    }

    public boolean postData(String fortune){

        //Traitement des communications vers Twitter
        Log.w("DEBUG_DATA","postData " + fortune);

        return true;
    }
}

Avec ce programme, chaque fois que vous testez Fortune Machine, le client Twitter publiera des données et vous devrez faire attention lors de l'expansion. Utilisons donc Dagger2 pour injecter le client Twitter dans Fortune Machine.

[2] Échantillon d'injection dépendant utilisant @Inject, @Component

[app]build.gradle


    implementation "com.google.dagger:dagger:2.11"
    implementation "com.google.dagger:dagger-android-support:2.11"
    annotationProcessor "com.google.dagger:dagger-android-processor:2.11"
    annotationProcessor "com.google.dagger:dagger-compiler:2.11"

MainActivity.java


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //FortuneMachine fortuneMachine = new FortuneMachine();
        Machine fortuneMachine = DaggerMainActivity_Machine.create();
        String result = fortuneMachine.maker().checkFortune();

        Log.w( "DEBUG_DATA", "result = " + result);
    }

    //Décrire les objets dépendants dans Dagger2
    @Component
    interface Machine{
        FortuneMachine maker();
    }
}

FortuneMachine.java


public class FortuneMachine {

    //C'est le même traitement que New
    @Inject
    TwiterClient twiterClient;

    String[] fortunes = {"Daikichi","Nakayoshi","Kokichi","Mal","大Mal"};

    //Également requis pour les constructeurs
    @Inject
    public FortuneMachine(){
        // twiterClient = new TwiterClient();
    }

    public String checkFortune(){
        int no = getRandomNo();
        twiterClient.postData(fortunes[no]);
        return fortunes[no];
    }

    public int getRandomNo(){
        Random r = new Random();
        int n = r.nextInt(fortunes.length);

        return n;
    }
}

TwitterClient.java


public class TwitterClient {

    //Également requis pour les constructeurs
    @Inject
    public TwitterClient(){
    }

    public boolean postData(String fortune){

        //Traitement des communications vers Twitter
        Log.w("DEBUG_DATA","postData " + fortune);

        return true;
    }
}

・ Changement 1

Ajout de paramètres à build.gradle pour utiliser Dagger2.

・ Changement 2

La partie qui crée une instance de TwiterClient dans FortuneMachine est ------------------------------- @Inject TwiterClient twitter ------------------------------- Il est devenu. Les constructeurs Fortune Machine et Twitter Client ont également @Inject.

Il s'agit d'une règle attachée à la variable de l'instance que vous souhaitez créer par injection de dépendances et au constructeur placé sous gestion. (Règles compliquées à ce stade)

・ Changement 3

Dans l'activité principale ------------------------------- @Component interface Machine{     FortuneMachine maker(); } ------------------------------- A été ajouté Création d'instance ------------------------------- Machine fortuneMachine = DaggerMainActivity_Machine.create(); ------------------------------- Il est devenu.

@Component est l'endroit où les dépendances sous le contrôle de Dagger2 sont rassemblées. (Gestion complète?) Vous pouvez changer de créateur () librement, mais vous devez vous souvenir du format. Une fois que vous avez écrit ceci et compilé, DaggerMainActivity_Machine implements MainActivity.Machine Un fichier avec la classe écrite apparaîtra. (Les détails sont décrits dans \ [Introduction à dagger2 (2.11) qui est très facile à comprendre ] dans l'URL de référence.) Vous devez vous souvenir de la règle nommée Dagger [nom de la classe] _ [nom de l'interface] qui est automatiquement générée ...

Pour obtenir cette instance, ajoutez .create ().

Désormais, le client Twitter n'est pas nouveau dans Fortune Machine, Celui instancié en externe est censé être injecté dans la Fortune Machine.

Comme vous pouvez le voir en faisant jusqu'à présent, il n'y a presque aucun mérite malgré la gêne! !! Cependant, étudions car ce sera pratique si nous le développons désormais: grenouille:

[3] Exemple pour changer le contenu de l'injection à l'aide de @Module, @Provide

Ce que je veux faire, c'est que je puisse contrôler ce que j'injecte et définir si je dois télécharger sur Twitter ou Facebook sans avoir à jouer avec Fortune Machine.

Pour le dire brièvement au début, j'ai créé et implémenté des interfaces. Gérons le contenu dans une classe appelée FortuneModuel et apprenons-le à @Component, qui est en gestion générale.

[app]build.gradle


Comme ci-dessus

MainActivity.java


public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //FortuneMachine fortuneMachine = new FortuneMachine();
        Machine fortuneMachine;
        // fortuneMachine = DaggerMainActivity_Machine.create();
        fortuneMachine = DaggerMainActivity_Machine.builder()
                .fortuneModule(new FortuneModule())
                .build();
        String result = fortuneMachine.maker().checkFortune();

        Log.w( "DEBUG_DATA", "result = " + result);
    }

    //Décrire les objets dépendants dans Dagger2
    //Décrivez le module à utiliser
    @Component(modules = FortuneModule.class)
    interface Machine{
        FortuneMachine maker();
    }
}

FortuneMachine.java


public class FortuneMachine {

    //C'est le même traitement que New
    @Inject
    Client clinet;

    String[] fortunes = {"Daikichi","Nakayoshi","Kokichi","Mal","大Mal"};

    //Également requis pour les constructeurs
    @Inject
    public FortuneMachine(){
    }

    public String checkFortune(){
        int no = getRandomNo();
        clinet.postData(fortunes[no]);
        return fortunes[no];
    }

    public int getRandomNo(){
        Random r = new Random();
        int n = r.nextInt(fortunes.length);

        return n;
    }
}

Client.java


public interface Client {
    boolean postData(String fortune);
}

TwitterClient.java


public class TwitterClient implements Client{

    //Également requis pour les constructeurs
    @Inject
    public TwitterClient(){
    }
    public boolean postData(String fortune){

        //Traitement des communications vers Twitter
        Log.w("DEBUG_DATA","postTwitter " + fortune);

        return true;
    }

}

FacebookClient.java


public class FacebookClient implements Client {
    
    //Également requis pour les constructeurs
    @Inject
    public FacebookClient(){
    }

    public boolean postData(String fortune){

        //Traitement de la communication vers Facebook
        Log.w("DEBUG_DATA","postFacebook" + fortune);

        return true;
    }
}

FortuneModule.java


//Classe qui fournit ce qui est injecté
// ...Nommez-le Module
@Module
public class FortuneModule {

    //Fournir ce qui est injecté
    // provide...Appeler
    @Provides
    static Client provideClient(){
        return new FacebookClient();
    }
}

・ Changement 1

Créez un client d'interface publique. TwitterClient et FacebookClient en ont hérité, Vous pouvez définir @Inject de FortuneMachine dans Clinet et recevoir la valeur.

・ Changement 2

Créez un module Fortune de classe publique. @Provides est attaché à la fonction qui gère ce qui est fourni à @Inject. @Module est attaché à la classe qui rassemble @Provides. Dans l'URL de référence \ [Je comprends cela (je pense que je comprends)! Dague 2 ] ---------------------------------------- Si @Inject est un port de ravitaillement de voiture, @Module est une station-service et @Provides est une machine de ravitaillement installée sur le stand. ---------------------------------------- L'analogie est excellente.

・ Changement 3

Un paramètre de module a été ajouté à @Component de MainActivity. ---------------------------------------- @Component(modules = FortuneModule.class) ---------------------------------------- En outre, la méthode de création d'une instance de DaggerMainActivity_Machine a été modifiée pour la version spécifiée du module. ---------------------------------------- fortuneMachine = DaggerMainActivity_Machine.builder() .fortuneModule(new FortuneModule()) .build(); ---------------------------------------- Il existe une fonction appelée fortuneModule en passant, mais je me demande si elle est générée automatiquement.

Maintenant, changez simplement la valeur de FoturneModule Vous pouvez définir le client à utiliser, définir Moc et tester.

〇Résumé

Pour être clair, il y a trop de manières et de règles mystérieuses. Il n'y a pratiquement aucun avantage à utiliser ce niveau de source. Vous devriez changer avec une instruction if autant que changer d'instance! ?? Cependant, l'exemple de source de Google est fourni avec Dagger, je ne peux donc m'empêcher de le comprendre ... Il semble pratique de l'utiliser avec ViewModel, donc cette fois.

Recommended Posts

Quoi qu'il en soit, résumé de Dagger2
Résumé orienté objet
résumé du ransack