Vzor návrhu v systému Android – Builder

Builder

Vzor Builder zjednodušuje vytváření objektů velmi přehledným a čitelným způsobem. Je velmi užitečný, když máme nějaké vzorové třídy s mnoha parametry. Některé z nich můžeme učinit nepovinnými nebo povinnými a nenutíme uživatele k použití určitého pořadí (jako v konstruktoru). Použitím vzoru Builder získáme elegantní řetězec metod. Nejčastější použití je ve třídě AlertDialog.Builder():

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

Jak můžeme vytvořit třídu Builder pro vlastní použití:

Builder v praxi

Předpokládejme, že máme nějakou modelovou třídu pro uživatele:

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

A namísto vytváření objektů této třídy pomocí konstruktorů je chceme vytvořit pomocí vzoru Builder takto:

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

Jak to můžeme udělat? Nejprve musíme uvnitř třídy User vytvořit třídu Builder, která bude mít metody pro konstrukci našeho objektu. Klíčem k tomu, abychom měli zřetězené metody, je to, že metody builderu vracejí třídu Builder. Podívejte se na příklad:

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

Pro každý parametr máme setter – rozdíl je v tom, že tyto metody vracejí typ Builder. Na konci máme metodu, která používá konstruktor ze třídy User a vrací objekt User – zde je skryt náš nepořádek.

Poté musíme vytvořit konstruktor se všemi parametry v modelové třídě 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;
}
}

Důležité je, že konstruktor User je soukromý, takže k němu nelze přistupovat z jiné třídy a pro vytvoření nového objektu musíme použít Builder.

Můžeme samozřejmě některé parametry učinit povinnými (protože zatím jsou všechny nepovinné) tím, že upravíme naši metodu create() a vyhodíme nějaké výjimky, například:

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

To je vše. Takto jsme vytvořili naši třídu User.Builder()!

Konstruktor – protip

Pokud jste byli dostatečně trpěliví, abyste se prokousali celým příspěvkem na blogu, mám pro vás jeden tip týkající se vzoru Builder: celou třídu Builder můžete vygenerovat pomocí IntelliJ!

Všechno, co musíte udělat, je umístit caret na konstruktor ve vaší třídě a v kontextovém menu zvolit Refactor -> Replace Constructor with Builder. Třída konstruktoru se všemi metodami bude automaticky vygenerována a připravena k použití.

Další informace si můžete přečíst zde: IntelliJ: Replace Constructor with Builder

Závěr

Vzor Builder je skvělý přístup nejen pro modelové třídy, ale pro každý objekt, který má více než tři nebo čtyři parametry. S trochou práce navíc můžeme zvýšit čitelnost našeho kódu. Návrhové vzory jsou uznávány jako osvědčené postupy, takže je velkou výhodou, pokud některý z nich znáte, a Builder je dobrým vzorem pro začátek.