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.