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;
    }
}

4voto

veysiertekin Points 786

Lombok est la façon la plus simple de le faire ! (Il dispose d'un plugin Intellij pour le support syntaxique. https://plugins.jetbrains.com/plugin/6317-lombok-plugin )

Il suffit d'ajouter un @Builder et derrière les murs, il ajoutera une implémentation du constructeur à l'intérieur de l'objet.

Avec Lombok :

import lombok.Builder;
import lombok.Singular;
import java.util.Set;

@Builder
public class BuilderExample {
  @Builder.Default private long created = System.currentTimeMillis();
  private String name;
  private int age;
  @Singular private Set<String> occupations;
}

Sans Lombok :

import java.util.Set;

public class BuilderExample {
  private long created;
  private String name;
  private int age;
  private Set<String> occupations;

  BuilderExample(String name, int age, Set<String> occupations) {
    this.name = name;
    this.age = age;
    this.occupations = occupations;
  }

  private static long $default$created() {
    return System.currentTimeMillis();
  }

  public static BuilderExampleBuilder builder() {
    return new BuilderExampleBuilder();
  }

  public static class BuilderExampleBuilder {
    private long created;
    private boolean created$set;
    private String name;
    private int age;
    private java.util.ArrayList<String> occupations;

    BuilderExampleBuilder() {
    }

    public BuilderExampleBuilder created(long created) {
      this.created = created;
      this.created$set = true;
      return this;
    }

    public BuilderExampleBuilder name(String name) {
      this.name = name;
      return this;
    }

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

    public BuilderExampleBuilder occupation(String occupation) {
      if (this.occupations == null) {
        this.occupations = new java.util.ArrayList<String>();
      }

      this.occupations.add(occupation);
      return this;
    }

    public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
      if (this.occupations == null) {
        this.occupations = new java.util.ArrayList<String>();
      }

      this.occupations.addAll(occupations);
      return this;
    }

    public BuilderExampleBuilder clearOccupations() {
      if (this.occupations != null) {
        this.occupations.clear();
      }

      return this;
    }

    public BuilderExample build() {
      // complicated switch statement to produce a compact properly sized immutable set omitted.
      Set<String> occupations = ...;
      return new BuilderExample(created$set ? created : BuilderExample.$default$created(), name, age, occupations);
    }

    @java.lang.Override
    public String toString() {
      return "BuilderExample.BuilderExampleBuilder(created = " + this.created + ", name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
    }
  }
}

Source : https://projectlombok.org/features/Builder

2voto

Gaket Points 1964

À mon avis, la façon la plus simple d'obtenir la classe statique interne au lieu d'une classe séparée est :

  1. Si vous n'avez pas encore de constructeur, générez-en un à l'aide de la commande Générer un dialogue constructeur
  2. Ensuite, utilisez Remplacer Constructor par Builder
  3. Déplacez la classe nouvellement créée vers la classe initiale à l'aide de la fonction Déplacer le remaniement (Touche de raccourci : F6)

0voto

tibtof Points 4492

En complément de la réponse de @CrazyCoder, je pense qu'il est très utile de savoir que dans la partie supérieure droite de Remplacer Constructor par Builder il existe un bouton de configuration que vous pouvez utiliser pour renommer le préfixe des setters.

0voto

rogerdpack Points 12806

Pour ceux qui veulent remplacer "too many parameters" par un modèle de constructeur, faites "extract parameter object" et ensuite le convert constructor to builder mentionné dans d'autres réponses ici.

0voto

Vijay Nandwana Points 497

Générer le constructeur de la classe par un clic droit sur la classe Générer>Constructeur. Ensuite, sur Windows, appuyez sur Ctrl+Shift+A pour trouver l'action et tapez "builder", sélectionnez "Remplacer le constructeur par builder "

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