Ontwerppatronen in Android – Builder

Builder

Builder patroon vereenvoudigt het maken van objecten op een zeer schone en leesbare manier. Het is zeer nuttig wanneer wij sommige model klassen met vele parameters hebben. We kunnen sommige van hen optioneel of verplicht maken, en we dwingen de gebruiker niet om een specifieke volgorde te gebruiken (zoals in de constructor). Door het Builder patroon te gebruiken krijgen we een elegante keten van methodes. De meest voorkomende toepassing is in AlertDialog.Builder() class:

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

Hoe kunnen we een Builder class maken voor ons eigen gebruik?

Builder in de praktijk

Laten we aannemen dat we een model class hebben voor de gebruiker:

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

En in plaats van objecten van deze class te maken met behulp van constructors, willen we ze maken met behulp van het Builder pattern zoals dit:

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

Hoe kunnen we dat doen? Ten eerste moeten we Builder klasse maken binnen User klasse die de methoden zal hebben om ons object te bouwen. De sleutel tot het hebben van chaining methoden is dat bouwer methoden Builder klasse retourneren. Kijk naar het voorbeeld:

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

Voor elke parameter hebben we een setter – het verschil is dat die methoden Builder type teruggeven. Aan het eind hebben we een methode die de constructor van de klasse User gebruikt en het object User teruggeeft – hier is de plaats waar onze puinhoop verborgen wordt gehouden.

Dan moeten we een constructor maken met alle parameters in de modelklasse 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;
}
}

Het belangrijkste hier is dat de constructor van User privé is, dus hij kan niet worden benaderd vanuit de andere klasse en we moeten Builder gebruiken om een nieuw object te maken.

Natuurlijk kunnen we sommige parameters verplicht maken (nu zijn ze allemaal optioneel) door onze create() methode aan te passen en enkele excepties te gooien, bijvoorbeeld:

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

Dat is het. Op deze manier hebben we onze User.Builder() class gemaakt!

Builder – protip

Als je geduldig genoeg was om de hele blog post door te komen, heb ik nog een tip voor je met betrekking tot het Builder pattern: je kunt de hele Builder class genereren met IntelliJ!

Het enige wat je hoeft te doen is de caret op de constructor in je class te zetten en in het context menu Refactor -> Replace Constructor with Builder te kiezen. De Builder class met alle methodes wordt automatisch gegenereerd, klaar voor gebruik.

Je kunt hier meer lezen: IntelliJ: Vervang Constructor door Builder

Conclusie

Builder pattern is een geweldige aanpak, niet alleen voor model classes maar voor elk object dat meer dan drie of vier parameters heeft. Met een beetje extra werk, kunnen we de leesbaarheid van onze code vergroten. Design patterns zijn erkend als de beste praktijk, dus het is een groot voordeel als je er een paar kent en Builder is een goede om mee te beginnen.