Design Patterns in Android – Builder
Builder
Il pattern Builder semplifica la creazione di oggetti in modo molto pulito e leggibile. È molto utile quando abbiamo alcune classi modello con molti parametri. Possiamo rendere alcuni di essi opzionali o richiesti, e non forziamo l’utente ad usare un ordine specifico (come nel costruttore). Usando il pattern Builder si ottiene l’elegante catena dei metodi. L’uso più comune è nella classe AlertDialog.Builder()
:
new AlertDialog.Builder(this)
.setTitle("Design Patterns")
.setMessage("Builder is awesome")
.create();
Come possiamo creare la classe Builder per il nostro uso?
Builder in pratica
Prevediamo di avere qualche classe modello per l’utente:
public class User {
private String firstName;
private String lastName;
private int age;
}
E invece di creare oggetti di questa classe usando i costruttori, vogliamo crearli usando il Builder pattern come questo:
new User.Builder()
.setFirstName("Leonardo")
.setLastName("da Vinci")
.setAge(67)
.create();
Come possiamo farlo? In primo luogo, abbiamo bisogno di creare la classe Builder
dentro la classe User
che avrà i metodi per costruire il nostro oggetto. La chiave per avere metodi concatenati è che i metodi costruttori restituiscono la classe Builder
. Guardate l’esempio:
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);
}
}
Per ogni parametro abbiamo un setter – la differenza è che quei metodi restituiscono il tipo Builder
. Alla fine abbiamo un metodo che usa il costruttore della classe User
e restituisce l’oggetto User
– qui è il posto dove il nostro casino è tenuto nascosto.
Allora, abbiamo bisogno di creare il costruttore con tutti i parametri nella classe modello 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 cosa importante qui è che il costruttore User
è privato, quindi non può essere accessibile dall’altra classe e dobbiamo usare Builder
per creare un nuovo oggetto.
Ovviamente, possiamo rendere alcuni dei parametri richiesti (per ora sono tutti opzionali) modificando il nostro metodo create()
e lanciando alcune eccezioni, per esempio:
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;
}
Ecco fatto. In questo modo abbiamo creato la nostra classe User.Builder()
!
Builder – protip
Se sei stato abbastanza paziente da leggere tutto il post del blog, ho un consiglio per te riguardo al pattern Builder: puoi generare l’intera classe Builder usando IntelliJ!
Tutto quello che devi fare è mettere il cursore sul costruttore nella tua classe e scegliere Refactor -> Replace Constructor with Builder nel menu contestuale. La classe Builder con tutti i metodi sarà generata automaticamente, pronta per l’uso.
Puoi leggere di più qui: IntelliJ: Replace Constructor with Builder
Conclusione
Il pattern Builder è un ottimo approccio, non solo per le classi modello ma per ogni oggetto che ha più di tre o quattro parametri. Con un po’ di lavoro aggiuntivo, possiamo aumentare la leggibilità del nostro codice. I design pattern sono riconosciuti come le migliori pratiche, quindi è un grande vantaggio conoscerne alcuni e Builder è un buon esempio per iniziare.