84 votes

Génération de code de type Builder dans IntelliJ

Existe-t-il un moyen d'automatiser l'écriture des patterns Builder dans IntelliJ ?

Par exemple, étant donné cette classe simple :

class Film {
   private String title;
   private int length;

   public void setTitle(String title) {
       this.title = title;
   }

   public String getTitle() {
       return this.title;
   }

   public void setLength(int length) {
       this.length = length;
   }

   public int getLength() {
       return this.length;
   }
}

Y a-t-il un moyen de faire en sorte que l'IDE génère ceci, ou quelque chose de similaire ?

public class FilmBuilder {

    Film film;

    public FilmBuilder() {
        film = new Film();
    }

    public FilmBuilder withTitle(String title) {
        film.setTitle(title);
        return this;
    }

    public FilmBuilder withLength(int length) {
        film.setLength(length);
        return this;
    }

    public Film build() {
        return film;
    }
}

110voto

CrazyCoder Points 103123

Utilisez le Remplacer Constructor par Builder le remaniement.

Pour utiliser cette fonction, cliquez sur la signature du constructeur dans votre code, puis faites un clic droit et sélectionnez le menu "Refactor", puis cliquez sur "Replace Constructor with Builder..." pour faire apparaître la boîte de dialogue permettant de générer le code.

25voto

Mansoor Siddiqui Points 5910

J'ai trouvé que la génération de modèles de construction intégrée dans IntelliJ était un peu maladroite pour plusieurs raisons :

  1. Il doit utiliser un constructeur existant comme référence.
  2. Il n'est pas rapidement accessible via le menu "Générer" ( command+N sur OS X).
  3. Il ne génère que des classes Builder externes. Comme d'autres l'ont mentionné, il est très courant d'utiliser des classes internes statiques lors de la mise en œuvre du modèle de construction.

El Plugin InnerBuilder répond à toutes ces lacunes et ne nécessite aucune installation ou configuration. Voici un exemple de Builder généré par le plugin :

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    private Person(Builder builder) {
        firstName = builder.firstName;
        lastName = builder.lastName;
        age = builder.age;
    }

    public static final class Builder {
        private String firstName;
        private String lastName;
        private int age;

        public Builder() {
        }

        public Builder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}

16voto

jFrenetic Points 1966

Voici comment surmonter le manquements mentionné par Mansoor Siddiqui :

1) Il doit utiliser un constructeur existant comme référence.

Ce qui est très facile à générer. Il suffit de taper Alt + Ins sur Windows pour invoquer le menu Générer et choisir Constructor .

2) Il n'est pas accessible rapidement via le menu "Générer" (commande+N sous OS X).

Il suffit d'aller sur Settings -> Keymap chercher Builder et lui attribuer un raccourci de votre choix (si vous utilisez cette fonctionnalité très souvent, ce qui est rarement le cas). Vous pouvez attribuer Alt + B par exemple.

Une autre alternative est Ctrl + Shift + A (Trouver une action). Commencez à taper Builder et vous aurez immédiatement accès à la commande :

Find Action dialog

Vous pouvez utiliser ce raccourci pour accéder rapidement à n'importe quelle fonctionnalité d'IntelliJ IDEA (cela est très utile lorsque vous ne vous souvenez pas exactement du nom de la commande et de l'endroit où la trouver).

3) Il ne génère que des classes Builder externes. Comme d'autres l'ont mentionné, il est très courant d'utiliser des classes Classes internes statiques lors de l'implémentation du modèle de construction.

Je préfère également que mes constructeurs soient des classes internes statiques. Malheureusement, il n'y a pas de moyen direct de le faire, mais c'est tout de même faisable. Il vous suffit de définir vous-même la classe interne imbriquée (en la laissant vide) et, lorsque vous invoquez la fonction Replace Constructor with Builder choisissez Use existing et sélectionnez votre classe intérieure. Ça marche comme sur des roulettes ! Bien que, il aurait été plus facile de rendre cette option configurable.

12voto

PålOliver Points 750

Si vous vous demandez si cela peut être utilisé pour créer une classe avec une classe de construction interne comme décrit par Joshua Block - il suffit de définir d'abord une classe interne vide, puis de cocher "Utiliser existant" et de rechercher la classe interne nouvellement créée et de cliquer sur "Refactor".

PS ! Le curseur doit résider dans le constructeur (pré-écrit) afin d'utiliser la fonction de refactoring "Replace Constructor with Builder".

5voto

La méthode IntelliJ pour y parvenir est, à mon avis, alambiquée. Il existe deux plugins (je préfère celui-ci : https://plugins.jetbrains.com/plugin/7354 ) qui remplissent bien mieux cette fonction.

Par exemple, je préfère avoir la classe Builder comme une classe interne de la PoJo. Pour y parvenir avec IntelliJ, vous avez besoin de quelques coups supplémentaires.

Un autre avantage de ce plugin est l'emplacement de la fonctionnalité (dans la page d'accueil du site). Generate... menu contextuel).

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