Design Patterns in Android – Builder

Builder

Le pattern Builder simplifie la création d’objets de manière très propre et lisible. Il est très utile lorsque nous avons certaines classes de modèle avec de nombreux paramètres. Nous pouvons rendre certains d’entre eux optionnels ou requis, et nous ne forçons pas l’utilisateur à utiliser un ordre spécifique (comme dans le constructeur). En utilisant le pattern Builder nous résultons avec la chaîne élégante des méthodes. L’utilisation la plus courante est dans la classe AlertDialog.Builder():

new AlertDialog.Builder(this)
.setTitle("Design Patterns")
.setMessage("Builder is awesome")
.create();

Comment pouvons-nous créer une classe Builder pour notre propre usage?

Builder en pratique

Supposons que nous ayons une classe modèle pour l’utilisateur:

public class User {
private String firstName;
private String lastName;
private int age;
}

Et au lieu de créer des objets de cette classe en utilisant des constructeurs, nous voulons les créer en utilisant le pattern Builder comme ceci:

new User.Builder()
.setFirstName("Leonardo")
.setLastName("da Vinci")
.setAge(67)
.create();

Comment pouvons-nous le faire ? Tout d’abord, nous devons créer la classe Builder à l’intérieur de la classe User qui aura les méthodes pour construire notre objet. La clé pour avoir des méthodes de chaînage est que les méthodes du constructeur retournent la classe Builder. Regardez l’exemple:

static class Builder {
private String firstName;
private String lastName;
private int age;
public Builder setFirstName(final String firstName) {
this.firstName = firstName;
return this;
}
public Builder setLastName(final String lastName) {
this.lastName = lastName;
return this;
}
public Builder setAge(final int age) {
this.age = age;
return this;
}
public User create() {
return new User(this);
}
}

Pour chaque paramètre nous avons un setter – la différence est que ces méthodes retournent le type Builder. A la fin, nous avons une méthode qui utilise le constructeur de la classe User et renvoie l’objet User – voici l’endroit où notre désordre est gardé caché.

Alors, nous devons créer le constructeur avec tous les paramètres de la classe modèle User :

public class User {
private String firstName;
private String lastName;
private int age;
private User(final Builder builder) {
firstName = builder.firstName;
lastName = builder.lastName;
age = builder.age;
}
}

La chose importante ici est que le constructeur User est privé, donc il ne peut pas être accédé depuis l’autre classe et nous devons utiliser Builder pour créer un nouvel objet.

Bien sûr, nous pouvons rendre certains des paramètres obligatoires (car pour l’instant tous sont optionnels) en modifiant notre méthode create() et en lançant quelques exceptions, par exemple :

public User create() {
User user = new User(firstName, lastName, age);
if (user.firstName.isEmpty()) {
throw new IllegalStateException(
"First name can not be empty!");
}
return user;
}

C’est tout. De cette façon, nous avons créé notre classe User.Builder()!

Builder – protip

Si vous avez été assez patient pour parcourir tout le billet de blog, j’ai une astuce pour vous concernant le pattern Builder : vous pouvez générer la classe Builder entière en utilisant IntelliJ!

Tout ce que vous avez à faire est de placer l’insigne d’insertion sur le constructeur dans votre classe et de choisir Refactor -> Replace Constructor with Builder dans le menu contextuel. La classe Builder avec toutes les méthodes sera générée automatiquement, prête à être utilisée.

Vous pouvez lire plus ici : IntelliJ : Remplacer le constructeur par Builder

Conclusion

Le pattern Builder est une excellente approche, non seulement pour les classes de modèle mais pour tout objet qui a plus de trois ou quatre paramètres. Avec un peu de travail supplémentaire, nous pouvons augmenter la lisibilité de notre code. Les design patterns sont reconnus comme la meilleure pratique, donc c’est un grand avantage si vous connaissez certains d’entre eux et Builder est un bon pour commencer.